debug a problem involving Embedding Basics
Fast recall
Quick revision
Core answer
Practical understanding of Embedding Basics.
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
The conflict resolution rules, in order:
- 1
Depth wins: an outer type's own Name at depth 0 beats both embedded Names at depth 1 — the outer name SHADOWS, no ambiguity (access the inners via the explicit path).
- 2
Same depth is ambiguous: two embedded types both providing Name at depth 1 — x.Name doesn't compile:
type A struct{ Name string }
type B struct{ Name string }
type C struct{ A; B }
c := C{A: A{"a"}, B: B{"b"}}
c.Name // compile error: ambiguous selector
c.A.Name // "a" — the resolution
c.B.Name // "b"- 3Methods follow the same rules — two embedded types with Greet: c.Greet() ambiguous; c.A.Greet() explicit. And a method-vs-field tie at the same depth is also ambiguous (the selector can't choose).
The design choice: Go could have picked an order rule (first-embedded wins) — common in other composition systems — and rejected it: silent winner-picking breaks when someone reorders the embedded declarations (a refactor no reviewer would suspect). The ambiguity error makes the conflict VISIBLE at every use, forcing the explicit path — and the full path is self-documenting about which embedded type's member is meant.
The diamond case people ask about — A and B both embedding Base, then C embedding A and B: C sees Base's members at depth 2 through two paths. Same rule: any Base member referenced unqualified through C is ambiguous (two depth-2 routes); resolved via c.A.Base.X / c.B.Base.X. No diamond problem though — there's no shared SINGLE Base instance (the copies are independent — value embedding copies twice), and no virtual dispatch to disagree about. The ambiguity is lexical, the resolution is explicit, and the semantics (two separate Base sub-objects) are exactly what the memory layout says: embedding is fields, and fields don't unify.
The practical hygiene rule that falls out: keep embedded surfaces DISJOINT by design. Embed types with distinct field/method vocabularies (the(Logger) + the(Store) — no overlap, full promotion, zero ambiguity), and when overlap is real, prefer a named field for one of them — the ambiguity disappears entirely, because the name separates the surfaces.
debug a problem involving Embedding Basics
Direct Answer
Ambiguity at that name: the outer reference x.Name is a compile error ('ambiguous selector'). The explicit paths resolve it: x.A.Name / x.B.Name. Shallower names shadow; same-depth ties need the full path.
Deep Dive & Architecture
The ambiguity rule's mechanics: the selector resolution computes the set of candidate paths to the name at the SHALLOWEST depth where the name exists. One path — promoted. Two-plus paths at that depth — ambiguous — and the compiler reports it ('ambiguous selector'), refusing to pick. The design review that produced this: an order rule (first embedded wins) would be arbitrary-but-silent — reordering the embeds would change meaning with no error at any use site, the worst kind of breakage (semantic, invisible, version-controlled as 'just moved a field'). The ambiguity error makes every conflict explicit and forces the qualified name — which self-documents WHICH embedded type the member came from.
The diamond (A and B both embedding Base, C embedding A and B) follows the same rule — Base's members sit at depth 2 through two paths, so unqualified access is ambiguous, resolved via c.A.Base.X. But note what does NOT happen: no diamond PROBLEM — because there's no single shared Base to disagree about (value embedding copies twice — two independent Base sub-objects) and no dispatch to unify them. The ambiguity is lexical; the semantics are just two fields that happen to have the same type — which is what the memory says: embedding is fields, and fields don't unify.
The hygiene rule that prevents the whole class: embed types with disjoint surfaces (Logger + Store — no overlap, full promotion, zero ambiguity), and when real overlap exists, name one of the fields — the name separates the surfaces and the ambiguity vanishes before it can be discovered at a use site three files away.
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 Embedding Basics, and when would you use it?
- When would you use Embedding Basics in a real project?
- How would you compare Embedding Basics with an alternative?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.