Embedding Basics
Fast recall
Quick revision
Core answer
Whether you understand Embedding Basics beyond memorized syntax.
Giving a definition without explaining a practical trade-off.
Connect the concept to a small production example and state its complexity or failure mode.
Interview-ready guide
Interview answer
Embedding is declaring a field with no explicit name — the type name becomes it:
type User struct{ Name string; Age int }
func (u User) Greet() string { return "hi " + u.Name }
type Admin struct {
User // embedded — field name IS 'User'
Level int
}
a := Admin{User: User{Name: "Root", Age: 40}, Level: 9}
fmt.Println(a.Name, a.Greet(), a.Level) // Root hi Root 9 — promotedExecuted. Both the field (Name) and the method (Greet) arrive on Admin. That promotion is the feature: the embedded type's exported fields and methods become part of the outer type's surface, reachable without naming the embedded type — unless shadowed by an outer declaration.
What embedding provides, precisely: reuse (Admin carries User's implementation), promotion (unqualified access), interface satisfaction through promotion (if User satisfies Greeter, Admin does too — the embedded methods count in Admin's method set), and delegation wiring (embed an interface, and the struct satisfies it while forwarding to the concrete value stored in the field).
What it is NOT, and the distinction is the interview's core: inheritance. No subtype (Admin is not a User — no assignment, no polymorphism), no overriding (an outer Greet SHADOWS; User's remains via a.User.Greet()), no dynamic dispatch (method calls bind to the receiver type statically). Embedding is composition with sugar — the sugar being that the inner's surface appears on the outer.
Embedding Basics
Direct Answer
An unnamed field whose type name acts as the field name: type Admin struct { User; Level int }. The embedded type's fields and methods are PROMOTED — admin.Name and admin.Greet() work. Composition, not inheritance.
Deep Dive & Architecture
The mechanics under promotion, once more because it's the heart: name resolution is a depth-first walk. a.Level: found at depth 0 (Admin's own fields). a.Name: no depth-0 hit, descend into every embedded type (depth 1) — User has it — promoted. Shadowing: an outer Name at depth 0 wins before the walk descends. Ambiguity: TWO embedded types both providing Name at depth 1 — neither promotes (a.Name is a compile error); the explicit a.UserA.Name / a.UserB.Name resolves it.
The method promotion is a wrapper: a.Greet() compiles to the method-value equivalent of a.User.Greet() — receiver is the INNER struct. Two consequences: (1) the method's body sees the INNER's scope (its own promoted lookups resolve within User's chain, not Admin's — shadowing rules apply inside-out); (2) the method SET of Admin includes a Greet wrapper — which is what makes Admin satisfy Greeter — interface satisfaction composes through embedding, and that's the composition idiom's backbone.
Embedding an interface — the delegation pattern: type Handler struct { io.Reader } — Handler now HAS a Read method (promoted from the field), calls forward to whatever Reader was assigned to the field, AND Handler satisfies io.Reader. This is how wrappers get interface compliance for free: embed the interface you wrap, override only what you change, everything else forwards automatically. The standard library's shape everywhere: sort.Reverse embeds a sort.Interface and overrides Less — three lines that would be twenty in a hand-built wrapper.
The layout fact that surprises: the embedded field occupies real storage, exactly as a named field would (a.User is an actual User in Admin's memory). Embedding is purely a name-resolution + method-set convention laid over an ordinary field — which is why the SAME struct can embed AND name the same type: struct { User; other User } — two fields, one promoted path, one explicit. All the magic is lexical; none of it is structural.
Common Mistakes & Pitfalls
Giving a definition without explaining a practical trade-off.
Check your understanding
Answer these without looking back at the article.
- When would you use Embedding Basics in a real project?
- How would you compare Embedding Basics with an alternative?
- What is a common mistake when using Embedding Basics?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.