Struct embedding
Let's say we want to create a workshop based on our Course struct.
We could create a new struct Workshop and copy all the fields from Course into it. But that would be a lot of duplication.
Let's start by creating a new struct Workshop:
type Workshop struct {
Course Course
Date time.Time
}
We can instantiate and print it:
func main() {
var w = Workshop{
Course: Course{Name: "Go", Instructor: Instructor{FirstName: "Lasse", LastName: "Jensen"}},
Date: time.Now(),
}
fmt.Printf("%v", w)
}
Looks good? Well, it works, but we can do better.
To avoid duplication, we can embed the Course struct into the Workshop struct:
type Workshop struct {
Course
Date time.Time
}
We simply remove the identifier Course and keep the type to embed it.
Is it extending the
Coursestruct? No, under the hood it copies the fields fromCourseintoWorkshop.
A downside of using embedding is that fields cannot be set directly when creating an instance of the Workshop struct.
func main() {
var w = Workshop{
Name: "Go", // Error: unknown field 'Name' in struct literal
Instructor: Instructor{FirstName: "Lasse", LastName: "Jensen"}, // Error: unknown field 'Instructor' in struct literal
Date: time.Now(),
}
fmt.Printf("%v", w)
}
To set the fields, we need to use the Course type:
func main() {
var w = Workshop{
Course: Course{Name: "Go", Instructor: Instructor{FirstName: "Lasse", LastName: "Jensen"}},
Date: time.Now(),
}
fmt.Printf("%v", w)
}
One way to make this look nicer is to use the factory pattern:
func NewWorkshop(courseName string, instructor Instructor, date time.Time) Workshop {
return Workshop{
Course: Course{Name: courseName, Instructor: instructor},
Date: date,
}
}
Order of properties
What happens if we have the same field in both the Workshop and Course structs?
type Workshop struct {
Course
Date time.Time
Name string // Error: duplicate field 'Name' ???
}
Will we get an error? No, Go will use the field from the
Workshopstruct as it is the "closest".
We can still set the name of the Course.Name field, but we need to be explicit:
w.Name = "Go workshop"
w.Course.Name = "Go course"
w.Course.Nameis also called an embedding property.
Sharing of methods
When you embed a struct, you also get access to its methods. Neat!