debug a problem involving Struct Definition
Fast recall
Quick revision
Core answer
Practical understanding of Struct Definition.
Repeating a definition without saying when to use it.
Give one trade-off and say how you would test it.
Interview-ready guide
Interview answer
Same inner type, two declarations, completely different reach:
type Admin struct {
User // embedded: promoted access
Level int
}
type Manager struct {
user User // named: namespaced access
Level int
}
a.Name // works — User's field promoted
m.user.Name // required — user is a namespace
a.Greet() // works — promoted method
m.user.Greet() // requiredInterface satisfaction differs exactly the same way: Admin (with Greet promoted) satisfies Greeter; Manager does not — its user does, but the interface check happens on the outer type's method set.
Choosing between them is an API-design question with a clean answer: embed when the outer IS-A-USER for interface purposes (the composed type should satisfy the inner's interfaces — Logger embedded in App so App satisfies Logger) and when the promoted surface is wanted (unqualified access to the inner's API). Name the field when the inner is a component, not an identity — a Config struct holding a Logger is 'has-a logger': you want cfg.Logger.Infof explicit, the composition hidden, and the outer's API kept small.
The overriding/shadowing semantics also differ: embedding's promotion can be shadowed (outer redeclares Name — inner still reachable via a.User.Name); a named field can't conflict at all (the field name IS the namespace). And the JSON-visible difference: embedded struct's fields flatten into the outer's JSON object; named struct's nest under its key — serialization shape often decides the declaration in API-layer structs.
debug a problem involving Struct Definition
Direct Answer
Embedding promotes the inner's fields/methods to the outer (a.Name works) and composes interface satisfaction. A named field keeps everything behind the field name (a.user.Name) and satisfies nothing through the outer.
Deep Dive & Architecture
The two declarations compile to the same memory layout — an embedded field IS a field (its name is the type name: a.User and m.user are equally real storage). Every difference is in the compiler's NAME RESOLUTION and METHOD SET rules — which is why the comparison is an API-design question, not a data-structure question.
Name resolution on the embedded form is the depth-walk described in the previous deep; on the named form it's one level and stop. The interesting cross-rule: an outer type can embed the SAME inner twice via different paths (one embedded, one named) — no ambiguity, because each path has a distinct name.
Method-set composition on embedding: the outer's method set gains the inner's promoted methods — and ONLY for interface satisfaction purposes; calling still routes to the inner. This is where 'embedding an interface' differs subtly from 'embedding a struct': embedding io.Reader as a field (unnamed, interface type) — the outer satisfies Reader, AND the implementation is whatever was assigned to the field — runtime delegation with compile-time checking. That's the pattern in io packages (bufio.Reader embedding io.Reader: the wrapper satisfies the interface while forwarding calls to whatever concrete reader was embedded). Named-field embedding of an interface is impossible — the interface type only has methods, nothing to promote as fields.
The design lesson the difference teaches: Go splits 'reuse and expose' (embed) from 'use and contain' (name) — one mechanism, two declarations, an explicit choice. Languages with inheritance conflate them; Go makes the composition relationship visible in the struct definition itself, and reviewers read intent directly from which form was chosen.
Common Mistakes & Pitfalls
Repeating a definition without saying when to use it.
Check your understanding
Answer these without looking back at the article.
- What is Struct Definition, and when would you use it?
- When would you use Struct Definition in a real project?
- How would you compare Struct Definition with an alternative?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.