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
结构的方法之间有什么区别?
我知道第二个是指针分配,但在实践中我看不出这个解决方案有什么不同。
答案 0 :(得分:3)
TL; DR 1 没有区别。是否在堆栈或堆上分配变量取决于其用法。
我在程序集上做了deep dive Go从各种初始化和调用情况生成。在v
和b
之间生成的程序集几乎相同。特别值得注意的是,d
未在堆栈 1 上分配。
确定变量是堆分配还是分配堆栈的方法是使用它的方式。将指针传递给仅将参数用作值的函数将不会强制将变量分配给堆。但即使这样也无法保证,规范允许任何Go编译器根据需要在堆栈之间自由移动变量以进行优化或代码生成。转发abstracts away Heap vs Stack就像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)
则会成立。我有点作弊回答了我认为你想问的问题。
答案 1 :(得分:2)
在这两种情况下,Vertex结构都以相同的方式初始化。
第一个表达式返回值,它是一个初始化的Vertex结构。使用6g的对齐规则,这意味着您将获得8 + 8 = 16字节的Vertex结构,因为每个float64的大小为8个字节。 第二个表达式分配内存,足够8 + 8 = 16个字节,将其用作Vertex结构,初始化它并返回一个指针,大小为4或8个字节,具体取决于您的体系结构。
在实践中存在许多差异。这两个值的方法集,Vertex结构和* Vertex指针可能不同。根据您需要传递Vertex结构的频率,将指针传递给它可能会或可能不会更有效。如果将Vertex结构传递给函数,该函数将获得一个副本,并且永远不会修改Vertex结构。如果传递*顶点,则可能会更改基础顶点。这可能是也可能不是你的意图:)