Go struct literals,为什么这个是可寻址的?
Go struct literals, why is this one addressable?
我正在看书"The Go Programming Language"。这对我们(相当)有经验的程序员来说非常好,并解释了其他语言的交叉点之间的差异——但我发现了一个我不完全理解的案例。
我对 C++ 非常了解,而且我知道 Go 调用(C++ 中的调用)rvalues/xvalues "non-addressable"。只有"variables" [GOPL的话]是可寻址的。
好的,很公平;有道理。
因此,例如,这是非法的(根据第一次印刷的第 159 页)
Point{1, 2}.ScaleBy(2) // compile error: can't take address of Point literal
因为 (*Point).ScaleBy
将 *Point
作为接收参数,而 Point
文字是不可寻址的。
(如果你还没有读过这本书,Point
是一个包含字段 X, Y float64
的结构体。
但是,在第 162 页,我们有
type ColoredPoint struct {
*Point
Color color.RGBA
}
p := ColoredPoint(&Point{1, 1}, red)
// ...more code ...
这显然是有效的并且可以编译。
问题:
为什么第二种情况下的 Point
文字是可寻址的?
这是为了方便而特例,还是我遗漏了一些大局?
为了方便起见,这是一个特例。规范提到了异常 here.
As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal.
为 Mellow Marmot 的回答添加更多细节:
Calling the built-in function new
or taking the address of a composite literal allocates storage for a variable at run time. Such an anonymous variable is referred to via a (possibly implicit) pointer indirection.
Point{1, 1}
是一个复合字面量,获取它的地址会在底层创建一个匿名变量,表达式的结果就是这个匿名变量的地址。
因此,正如您从技术上看到的那样,它是一个 变量 被寻址,因此它不违反这一点:
Only "variables" [GOPL's words] are addressable.
另请查看此答案,了解您还可以执行哪些其他 "goodies" 或技巧:
&T{}
表示法在第 4.4.1 节“结构文字”第 103 页中进行了解释:
Because structs are so commonly dealt with through pointers, it’s possible to use this shorthand notation to create and initialize a struct variable and obtain its address:
pp := &Point{1, 2}
It is exactly equivalent to
pp := new(Point)
*pp = Point{1, 2}
but &Point{1, 2}
can be used directly within an expression, such as a function call.
很高兴您喜欢这本书。
我正在看书"The Go Programming Language"。这对我们(相当)有经验的程序员来说非常好,并解释了其他语言的交叉点之间的差异——但我发现了一个我不完全理解的案例。
我对 C++ 非常了解,而且我知道 Go 调用(C++ 中的调用)rvalues/xvalues "non-addressable"。只有"variables" [GOPL的话]是可寻址的。
好的,很公平;有道理。
因此,例如,这是非法的(根据第一次印刷的第 159 页)
Point{1, 2}.ScaleBy(2) // compile error: can't take address of Point literal
因为 (*Point).ScaleBy
将 *Point
作为接收参数,而 Point
文字是不可寻址的。
(如果你还没有读过这本书,Point
是一个包含字段 X, Y float64
的结构体。
但是,在第 162 页,我们有
type ColoredPoint struct {
*Point
Color color.RGBA
}
p := ColoredPoint(&Point{1, 1}, red)
// ...more code ...
这显然是有效的并且可以编译。
问题:
为什么第二种情况下的 Point
文字是可寻址的?
这是为了方便而特例,还是我遗漏了一些大局?
为了方便起见,这是一个特例。规范提到了异常 here.
As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal.
为 Mellow Marmot 的回答添加更多细节:
Calling the built-in function
new
or taking the address of a composite literal allocates storage for a variable at run time. Such an anonymous variable is referred to via a (possibly implicit) pointer indirection.
Point{1, 1}
是一个复合字面量,获取它的地址会在底层创建一个匿名变量,表达式的结果就是这个匿名变量的地址。
因此,正如您从技术上看到的那样,它是一个 变量 被寻址,因此它不违反这一点:
Only "variables" [GOPL's words] are addressable.
另请查看此答案,了解您还可以执行哪些其他 "goodies" 或技巧:
&T{}
表示法在第 4.4.1 节“结构文字”第 103 页中进行了解释:
Because structs are so commonly dealt with through pointers, it’s possible to use this shorthand notation to create and initialize a struct variable and obtain its address:
pp := &Point{1, 2}
It is exactly equivalent to
pp := new(Point) *pp = Point{1, 2}
but
&Point{1, 2}
can be used directly within an expression, such as a function call.
很高兴您喜欢这本书。