I am reading the book "The Go Programming Language". It is very good for us (rather) experienced programmers and explains the differences between the intersection of other languages -- but I've found a case which I do not understand fully.
I know C++ sufficiently good, and I understand that Go calls (what in C++ would be called) rvalues/xvalues "non-addressable". Only "variables" [GOPL's words] are addressable.
OK, fair enough; it makes sense.
And therefore, for instance, this is illegal (according to page 159 in the first printing)
Point{1, 2}.ScaleBy(2) // compile error: can't take address of Point literal
because (*Point).ScaleBy
takes a *Point
as a receiver argument, and a Point
literal is non-addressable.
(If you haven't read the book, Point
is a struct with the fields X, Y float64
.
However, on page 162, we have
type ColoredPoint struct {
*Point
Color color.RGBA
}
p := ColoredPoint(&Point{1, 1}, red)
// ...more code ...
which apparently is valid and will compile.
Question:
Why is the Point
literal in the second case addressable?
Is it a special case for convenience, or am I missing something in the big picture?
The &T{}
notation is explained in Section 4.4.1, Struct Literals, on page 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.
Glad you're otherwise enjoying the book.