AnyCompiler

Struct Embedding

Go has no class inheritance. Instead, you embed one struct inside another by listing its type with no field name — the outer type automatically gets direct access to the embedded type's fields and methods, a pattern called promotion.

package main

import "fmt"

type Animal struct {
	Name string
}

func (a Animal) Describe() string {
	return a.Name + " is an animal"
}

type Dog struct {
	Animal
	Breed string
}

func main() {
	d := Dog{Animal: Animal{Name: "Rex"}, Breed: "Labrador"}
	fmt.Println(d.Name)
	fmt.Println(d.Describe())
}
Output
Rex
Rex is an animal

Overriding a promoted method

d.Name and d.Describe() above are promoted straight from the embedded Animal, with no extra code needed. A type can also define its own method with the same name to take precedence over the embedded one, while still calling through to it explicitly, like Derived.Label does below.

package main

import "fmt"

type Base struct {
	ID int
}

func (b Base) Label() string {
	return fmt.Sprintf("Base#%d", b.ID)
}

type Derived struct {
	Base
	Name string
}

func (d Derived) Label() string {
	return fmt.Sprintf("%s (%s)", d.Base.Label(), d.Name)
}

func main() {
	d := Derived{Base: Base{ID: 7}, Name: "widget"}
	fmt.Println(d.Label())
}
Output
Base#7 (widget)

Next: the standard library — a couple of commonly used packages, and a closing look at what else Go's standard library provides.

Practice exercise

Define a struct Vehicle with field Wheels int. Define a struct Car that embeds Vehicle and adds a field Brand string. Create a Car with Wheels 4 and Brand "Toyota", then print car.Wheels and car.Brand.