Go Structs in Depth
Struct embedding places one struct inside another struct without a field name. The fields and methods of the inner struct then read through the outer struct.
An embedded struct promotes its fields and methods
Dog embeds Animal by naming the type alone. The Name field and the Speak method of Animal read through the Dog value.
package main
import "fmt"
type Animal struct {
Name string
Legs int
}
func (a Animal) Speak() string {
return a.Name + " makes a sound"
}
type Dog struct {
Animal
Breed string
}
func main() {
d := Dog{Animal: Animal{Name: "Rex", Legs: 4}, Breed: "Collie"}
fmt.Println(d.Name)
fmt.Println(d.Speak())
fmt.Println(d.Breed)
}An outer field hides a promoted field
Car embeds Wheels and Engine and adds its own Power field. The name Power reads the outer field, and the full path reads the inner one.
package main
import "fmt"
type Wheels struct {
Count int
}
type Engine struct {
Power int
}
type Car struct {
Wheels
Engine
Power int
}
func main() {
c := Car{Wheels: Wheels{Count: 4}, Engine: Engine{Power: 150}, Power: 200}
fmt.Println(c.Count)
fmt.Println(c.Power)
fmt.Println(c.Engine.Power)
}An anonymous struct for a one-off shape
A struct type can be written inline where a value is built. The value needs no named type when the shape serves one place.
package main
import "fmt"
func main() {
point := struct {
X int
Y int
}{X: 3, Y: 5}
fmt.Println(point.X, point.Y)
fmt.Println(point.X + point.Y)
}Struct values compare with ==
Two values of the same struct type compare field by field. Equal fields print true, and one different field prints false.
package main
import "fmt"
type Size struct {
W int
H int
}
func main() {
a := Size{W: 2, H: 3}
b := Size{W: 2, H: 3}
c := Size{W: 3, H: 2}
fmt.Println(a == b)
fmt.Println(a == c)
}Example
package main
import "fmt"
type Customer struct {
Name string
City string
}
type Order struct {
Customer
Item string
Qty int
}
func main() {
o := Order{Customer: Customer{Name: "Hana", City: "Seattle"}, Item: "Pen", Qty: 3}
fmt.Println(o.Name)
fmt.Println(o.City)
fmt.Println(o.Item)
fmt.Println(o.Qty)
}Key points
- An embedded field is written as a type name with no field name of its own.
- A promoted field is an inner field read through the outer value with one dot.
- A promoted method is an inner method called on the outer value.
- An outer field with the same name hides the promoted field of that name.
- The full path through the inner type name still reaches a hidden field.
- An anonymous struct is a struct value built without a named type.
- Two struct values compare with == when all their fields can compare.
In this example, Order embeds Customer and adds Item and Qty. The literal sets the Customer part with its type name. The first print line reads the promoted Name field. The second line reads the promoted City field. The last two lines read the fields of Order itself.
Note
The inner struct keeps its own value inside the outer struct, so one outer value holds both sets of fields.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Go Playground
Exercise
A Dog struct embeds Animal, and Animal has a Name field. The Dog value is named d. Which line prints the promoted Name?