When I introduced structs last week, I skipped over one sentence. Today I’m going to address that.
Struct types
A struct is a sequence of named elements, called fields, each of which has a name and a type. Field names may be specified explicitly (IdentifierList) or implicitly (EmbeddedField). Within a struct, non-blank field names must be unique.
We already saw how field names are expressed explicitly. But what is an embedded field? Well, I’m glad you asked. Because the next sentence in the spec tells us, followed by some examples:
A field declared with a type but no explicit field name is called an embedded field. An embedded field must be specified as a type name
T
or as a pointer to a non-interface type name*T
, andT
itself may not be a pointer type. The unqualified type name acts as the field name.// A struct with four embedded fields of types T1, *T2, P.T3 and *P.T4 struct { T1 // field name is T1 *T2 // field name is T2 P.T3 // field name is T3 *P.T4 // field name is T4 x, y int // field names are x and y }
You may be wondering why we would ever use embedded struct fields, and the short answer is that this is one way Go gives us to accomplish composition. And we’ll talk more about methods on embedded types later. For now, let’s just consider how embedding can be useful for data.
type Person struct {
Name string
Age int
}
type Employee struct {
Person
StartDate time.Time
}
In this very example, the Employee
type embeds the Person
type. This is roughly (though not exactly) the same as:
type Employee struct {
Person Person
StartDate time.Time
}
By embedding the Person
type within the Employee
type, we’re effectively establishing a “has a” relationship. In other words, Employee
has a Person
.
And as a final note, the uniqueness constraint on field names is still enforced on embedded field names:
The following declaration is illegal because field names must be unique in a struct type:
struct { T // conflicts with embedded field *T and *P.T *T // conflicts with embedded field T and *P.T *P.T // conflicts with embedded field T and *T }
Quotes from The Go Programming Language Specification Version of December 15, 2022