Why does inline instantiation of variable requires explicitly taking the address of it to call pointer method, while for a existing var its implict

前端 未结 2 1860
星月不相逢
星月不相逢 2021-02-02 01:25

Is there a reason for this behaviour? I would like to know what is different in the memory level. The compiler returns \"cannot take the address of composite literal\" while i c

2条回答
  •  礼貌的吻别
    2021-02-02 02:10

    Is there a reason for this behaviour?

    The reason for the behavior is that there is an exception to addressability for that specific notation and the reason for that exception is explained here by one of the Go maintainers :

    They're special because we decided that the notation was useful enough for constructors to merit a special case:

    Taking the address of a composite literal (§Address operators) 
    generates a unique pointer to an instance of the literal's value. 
    
    http://golang.org/doc/go_spec.html#Composite_literals
    

    Russ


    "Taking the address of a composite literal (§Address operators) generates a unique pointer to an instance of the literal's value." Could you elaborate that?

    I think that means the notation &Object{} notation is simply a literal pointer each time it is executed it creates a new instance of the value and a new pointer is created that points to the new value. The addressability exception simply results from the notation of this literal, it is unlike the other addressables because it is not being acted upon by the & operator.

    I would like an answer similar to jesse's on the "here" link you mentioned. That is for C. Can anyone confirm that for golang?

    My guess is this that this notation is helpful with escape analysis, which determines at compile time whether a references escapes the function and determines whether it should be allocated on the heap or the stack ( faster ). From what I understand the variables that have their address taken are considered candidates for escape analysis. Since one of Go's main goals is fast compilation I think reference creation and tracking is required to be clear.

    For example, for Item{}.Method() the need to create a pointer and therefore run escape analysis to the Item{} value would depend on the receiver type of the Method() whether it is *Item or just Item this unnecessarily complicates compilation. That's why you use the explicit notation &Item{} to construct a *Item.

提交回复
热议问题