My Confusion is shown in the following code snippet:
type Ex struct{
A,B int
}
a := []Ex{Ex{1, 2}, Ex{3, 4}} //it works, and I understand it
b := []*Ex{&Ex{1, 2}, &Ex{3, 4}} //it works, and I understand it
c := []Ex{{1, 2}, {3, 4}} //it works, and I don't understand it
d := []*Ex{{1, 2}, {3, 4}} //it works, and I don't understand it
e := []*Ex{{1, 2}, &Ex{3, 4}} //it works, and I don't understand it
What puzzles me most is that both c := []Ex{{1, 2}, {3, 4}}
and d := []*Ex{{1, 2}, {3, 4}}
can work well. Why can{1, 2}
be used to initialize both an object and a pointer?
I found the same question and someone answered:
If is a pointer like *Ex or *Track, it also automatically initializes correctly:
But I expect a deeper explanation. Is there any official documentation on this question?
I have a good C/C++ foundation, but a Golang novice. Looking forward to your answers, and I thank you in advance.
Within a composite literal of array, slice, or map type
T
, elements or map keys that are themselves composite literals may elide the respective literal type if it is identical to the element or key type ofT
. Similarly, elements or keys that are addresses of composite literals may elide the&T
when the element or key type is*T
.
This explains the cases c
, d
and also e
.
c := []Ex{{1, 2}, {3, 4}}
d := []*Ex{{1, 2}, {3, 4}}
e := []*Ex{{1, 2}, &Ex{3, 4}}
All these are slice composite literals, and elements are also provided using composite literals. So the quoted part applies. As per the spec, you may omit the element type of T
from the composite literals of the elements (and also the &
operator if it is a pointer type), in which case it is inferred from the element type of the slice (the "outer" composite literal).
In case of c
, {1, 2}
is interpreted as a composite literal Ex{1, 2}
.
In case of d
, {1, 2}
is interpreted as &Ex{1, 2}
, namely taking the address of the composite literal Ex{1, 2}
.
The same applies to case e
(since the element type of the slice is the same).
This is a simplification of composite literals allowed by the language spec. Repeating the element type for all elements when it's known from the slice type is simply redundant, makes code longer and harder to read.