We have 3 types:
type A struct {
B
C
}
type B struct {
x int
y string
}
type C struct {
z string
}
because of how fields and methods of an anonymous field are promoted, we can access fields of the anonymous field B
in A
like
var a A
a.x = 0
It is very obvious that type B
& C
embed in A
, so we expect A
to be equivalent to:
type D struct {
x int
y string
z string
}
We expect that we can write composite literals of type A
like that:
a := A{x: 2}
This compile error:
unknown field 'x' in struct literal of type A
Why isn't it possible to write composite literals for A
in that way, as it would for the type D
?
You need to explicitly use B
(and C
) when initializing A
:
a = A{B{x: 2}, C{}}
Rob 'Commander' Pike explained it here.
He wrote there:
It might one day, but as it stands the requirement to provide more information is more robust against changes in the data types.
If I understand and interpret that correctly, it is basically a safety measure for you. The compiler will yell at you, if the struct definition doesn't match the composite literal.
In your example, the definition of A
might change -- in a later change (as in much later, like years) -- to:
type A struct {
x int
y string
z string
}
later, but x
, y
and z
might represent different things than before and therefore it is better, that you have to change all your literals to not get silently corrupt data of some kind.
That is a deliberate choice. The wording in the language specification is:
Promoted fields act like ordinary fields of a struct except that they cannot be used as field names in composite literals of the struct.
So you can use the field x
of the field B
as if it was a field of A
except for composite literals.
And the types
type A struct {
B
C
}
and
type A struct {
x int
y string
z string
}
really are two different things. The former contains two fields B
and C
, and the latter three fields x
, y
and z
. The former just has some syntactic sugar to access the field x
of the field B
with a shorthand. So if a
is a variable of the former type A
, a.x
is syntactic sugar for a.B.x
.