The Golang Gopher

Golang Embedded Structs

Kevin Yang
2 min readMay 29, 2022

Golang doesn’t have the concepts of objects and inheritance. The design of the language is strongly opinionated and follows object-oriented principles (OOP)very closely, hence it favors composition over inheritance. Golang uses structs and methods to emulate objects. For example,

type Bird struct {
}
func (b Bird) makeSound() {
fmt.Println("chirp")
}

Golang allows you to compose structs inside of other structs. There are two ways of composing structs: anonymous embedded fields and explicit fields.

Anonymous Embedded Fields

An anonymous embedded field is a struct field that doesn’t have an explicit field name. Structs that have an anonymous field obtain all of the methods and properties of the nested struct. These methods and properties are called “promoted” methods and properties. Anonymous embedded fields can also be accessed by the type name directly.

type Eagle struct {
Bird // anonymous embedded field
}
e := Eagle{name: "Baldie"}
e.makeSound() // chirp
e.Bird.makeSound() // chirp

The nuance comes from when structs declare methods and properties that also exist on the embedded struct. In this case, the methods and properties from the embedded struct are “shadowed” and the methods and properties on the struct you are calling will be used. You can still access the shadowed methods and properties by specifically accessing the embedded field and then calling the method or property.

func (e Eagle) makeSound(){
fmt.Println("caw")
}
e.makeSound() // caw
e.Bird.makeSound() // chirp

Explicit Fields

You can also explicitly name a field to avoid confusion with promoted and shadowed fields.

type Eagle struct {
b Bird // explicit field
}
func (e Eagle) makeSound(){
fmt.Println("caw")
}
e := Eagle{name: "Baldie"}e.makeSound() // caw
e.b.makeSound() // chirp
e.Bird.makeSound() // error

Here, in order to call Bird’s makeSound() method, one has to explicitly access the nested Bird object using .b. It is no longer possible to access the underlying .Bird field.

Conclusion

In summary, there are two ways of composing structs in Golang: anonymous embedded fields and explicit fields.

Anonymous embedded fields allow methods and properties from the embedded struct to automatically get promoted to the nesting struct, but there’s a possibility of those methods and properties getting shadowed if the nesting struct declares methods of properties of the same name.

Explicit fields directly associate a field name with the nested struct, so that accessing the nested struct’s methods and properties are unambiguous. In production code, it’s often better to use explicit fields over anonymous embedded fields to make the code more readable and not surprise yourself with shadowed fields.

References

--

--

No responses yet