๐ŸงฉStruct EmbeddingLESSON

Struct Embedding

Go has no extends keyword. Instead, embedding achieves composition-based code reuse: the outer struct gets all fields and methods of the embedded type promoted to its own namespace, with no type hierarchy involved.

Basic struct embedding

Embed a type by writing its name alone โ€” no field name, no tag:

The compiler rewrites d.Speak() to d.Animal.Speak() โ€” it is syntactic sugar, not dynamic dispatch.

Method promotion rules

All exported methods and fields of the embedded type are promoted to the outer struct. You can always bypass promotion and access the embedded struct explicitly:

Unexported fields and methods are accessible within the same package but are not promoted across package boundaries.

Multiple embedding

A struct can embed more than one type. Each embedded type contributes its promoted set independently:

Overriding promoted methods

Define a method with the same name on the outer struct to shadow the promoted one:

After this definition d.Speak() calls Dog.Speak, but d.Animal.Speak() still reaches the original.

Embedding interfaces

Embedding an interface inside a struct declares that the struct satisfies that interface, and lets you build adapter/wrapper types:

You can also embed an interface inside another interface to compose larger interface contracts without repeating method signatures.

Field collision

If two embedded types expose a field or method with the same name, accessing it without qualification is a compile error โ€” the compiler cannot pick one automatically. Always qualify in that case:

Knowledge Check

What is the key difference between Go struct embedding and classical inheritance?

If Dog embeds Animal and both define a method `Speak()`, which version does `d.Speak()` call?

How do you access the embedded Animal struct's fields directly on a Dog value d?