在 gotour 中,有一个部分:struct literals。
package main
import "fmt"
type Vertex struct {
X, Y int
}
var (
v1 = Vertex{1, 2} // has type Vertex
v2 = Vertex{X: 1} // Y:0 is implicit
v3 = Vertex{} // X:0 and Y:0
p = &Vertex{1, 2} // has type *Vertex
)
func main() {
fmt.Println(v1, p, v2, v3)
}
Run Code Online (Sandbox Code Playgroud)
带有 & 符号的结构体和不带符号的结构体有什么区别?我知道带有 & 符号的那些指向相同的引用,但我为什么要在常规引用上使用它们呢?
var p = &Vertex{} // why should I use this
var c = Vertex{} // over this
Run Code Online (Sandbox Code Playgroud)
Yen*_*ang 29
确实,p
( &Vertex{}
) 有类型*Vertex
,c
( Vertex{}
) 有类型Vertex
。
但是,我不相信这种说法真的回答了为什么一个人会选择一个而不是另一个的问题。这有点像回答“为什么使用飞机而不是汽车”的问题,比如“飞机有翼,汽车没有”。(显然我们都知道翅膀是什么,但你懂的)。
但简单地说“去学习指针”也不会很有帮助(尽管我认为这是一个非常好的主意)。
你如何选择基本上归结为以下几点。
意识到这一点,&Vertex{}
并Vertex{}
从根本上以相同的方式初始化。
是什么使一个比另一个更有用和更高效取决于它们在程序中的使用方式。
“我想要一个指向 struct ( p
)的指针,还是只是 struct ( c
)?”
&
运算符(例如&c
)获取指针;您可以取消引用指针以使用*
(例如*p
)
获取值*p
或&c
Vertex{}
还是&Vertex{}
?
Vertex
您的示例中给出的内容,我会选择Vertex{}
获取一个简单的值对象。Vertex
在这个例子中,它的大小非常小。抄袭很便宜。Vertex
并不真正包含任何值得改变的东西(只需Vertex
在需要时返回/创建一个新的)。&Struct{}
Struct
有一个成员缓存一些需要在原始对象本身内部更改的状态。Struct
是巨大的,并且您已经进行了足够的分析来确定复制的成本是巨大的。
struct
的小,这只是一个很好的做法。 v := Struct{}
v2 := v // Copy happens
Run Code Online (Sandbox Code Playgroud) v := &Struct{}
v2 := v // Only a pointer is copied
Run Code Online (Sandbox Code Playgroud)评论几乎已经说明了这一点:
v1 = Vertex{1, 2} // has type Vertex
p = &Vertex{1, 2} // has type *Vertex
Run Code Online (Sandbox Code Playgroud)
与许多其他语言一样,采用其后的标识符的&
地址。当您需要指针而不是值时,这很有用。
如果您需要了解有关编程中指针的更多信息,您可以从 go 的this开始,甚至可以从wikipedia页面开始。