Struct Initialization with Embedded Structs in Go
Composing structs is a common practice in Go for code organization and reuse. However, initializing composed structs can present a challenge when a subfield is inherited from an embedded struct.
Consider the following example:
type Base struct { ID string } type Child struct { Base a int b int }
To initialize Child, one might expect to use the following syntax:
child := Child{ ID: id, a: a, b: b }
However, this will result in a compilation error due to the unknown field ID in the Child struct literal. To workaround this issue, the ID field must be initialized separately:
child := Child{ a: 23, b: 42 } child.ID = "foo"
This approach violates encapsulation principles by exposing the fact that ID is an embedded field. It also introduces the risk of breaking initialization if a public field is moved into an embedded struct.
To address this issue, there are two recommended solutions:
Nested Composite Literals:
Nested composite literals can be used to initialize an embedded field in a single expression:
child := Child{Base: Base{ID: id}, a: a, b: b}
Proposed Change in Go:
Go issue 9859 proposes a change to make composite literals consistent with field access for embedded types. If implemented, this change would allow the following syntax:
child := Child{ ID: id, a: a, b: b }
It's important to note that embedded types do not provide encapsulation in the true sense. An application can still directly access child.Base.ID despite using the child.ID syntax.
The above is the detailed content of How Can I Efficiently Initialize Embedded Structs in Go?. For more information, please follow other related articles on the PHP Chinese website!