2013-10-16 92 views

回答

2

在这两种情况下,Vertex结构都以相同的方式初始化。

第一个表达式返回一个初始化的Vertex结构体的值。使用6g的对齐规则,这意味着您将获得8 + 8 = 16字节的Vertex结构,因为每个float64的大小为8个字节。 第二个表达式分配内存,足够8 + 8 = 16个字节,将它用作Vertex结构,初始化它并返回一个指针,它的大小为4或8个字节,具体取决于您的体系结构。

实践中有许多差异。这两个值的方法集,Vertex结构和* V​​ertex指针可能不同。根据您需要绕过Vertex结构的频率,将指针传递给它可能会或可能不会更高效。如果您将Vertex结构传递给函数,该函数将获得副本,并且您的Vertex结构将永远不会被修改。如果您传递* Vertex,则可能会更改您的底层顶点。这可能或可能不是你的意图:)

2

TL; DR没有区别。是否在堆栈或堆上分配变量取决于其用法。

我做了一个deep dive上的程序集生成从各种初始化和调用情况。在vb之间生成的程序集几乎相同。特别值得注意的是,d未被分配到堆栈。

什么决定了变量是堆分配还是堆分配是它的使用方式。将传递指针传递给仅将该参数用作值的函数不会强制变量被堆分配。但即使这并不能保证,该规范允许任何Go编译器根据需要在堆栈和堆之间自由移动变量以进行优化或代码生成。正如C/C++抽象掉RAM vs Register一样,去abstracts away Heap vs Stack

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) 
} 

:技术上不正确的,但如果fmt.Println(*d)已经代替将是真实的。我骗了一些回答我认为你应该问的问题。