type Vertex struct {
X, Y float64
}
func main() {
v := Vertex{3, 4}
fmt.Println(v)
d := &Vertex{3, 4}
fmt.Println(d)
}
http://play.golang.org/p/XluyUHL2y7
这两种初始化Vertex
结构的方法有什么区别?
我知道第二个是指针分配,但在实践中我看不出这个解决方案有什么不同。
type Vertex struct {
X, Y float64
}
func main() {
v := Vertex{3, 4}
fmt.Println(v)
d := &Vertex{3, 4}
fmt.Println(d)
}
http://play.golang.org/p/XluyUHL2y7
这两种初始化Vertex
结构的方法有什么区别?
我知道第二个是指针分配,但在实践中我看不出这个解决方案有什么不同。
TL;DR没有区别1。变量是分配在栈上还是堆上取决于它的使用情况。
我对 Go 从各种初始化和调用案例生成的程序集进行了深入研究。v
和之间生成的程序集b
几乎相同。需要特别注意的d
是,没有分配在栈1上。
决定一个变量是堆分配还是堆栈分配的是它的使用方式。将指针传递给仅将参数用作值的函数不会强制变量进行堆分配。但即使这不能保证,该规范允许任何 Go 编译器根据优化或代码生成的需要在堆栈和堆之间自由移动变量。Go抽象出堆与堆栈,就像 C/C++ 抽象出 RAM 与寄存器一样。
http://play.golang.org/p/vJQvWPTGeR
type Vertex struct {
X, Y float64
}
func PrintPointer(v *Vertex) {
fmt.Println(v)
}
func PrintValue(v *Vertex) {
fmt.Println(*v)
}
func main() {
a := Vertex{3, 4} // not allocated
PrintValue(&a)
b := &Vertex{3, 4} // not allocated
PrintValue(b)
c := Vertex{3, 4} // allocated
PrintPointer(&c)
d := &Vertex{3, 4} // allocated
PrintPointer(d)
}
1:从技术上讲不正确,但如果fmt.Println(*d)
使用它会是正确的。我作弊回答了我认为你想问的问题。
In both cases, a Vertex struct is intialized in the same way.
The first expression returns value which is an initialized Vertex struct. With 6g's alignment rules, this means that you will get 8+8 = 16 bytes worth of Vertex struct, since every float64 is 8 bytes in size. The second expression allocates memory, enough for 8+8 = 16 bytes, uses it as a Vertex struct, initializes it and returns a pointer, which will be 4 or 8 bytes in size, depending on your architecture.
There are a number of differences in practice. The method sets of these two values, the Vertex struct and the *Vertex pointer, may be different. Depending on how often you need to pass around the Vertex struct, it might or might not be more efficient to pass a pointer to it. If you pass a Vertex struct to a function, the function gets a copy and your Vertex struct will never be modified. If you pass a *Vertex, your underlying Vertex might be changed. This might or might not be your intention :)