debug a problem involving Value Vs Pointer Receivers
Fast recall
Quick revision
Core answer
Practical understanding of Value Vs Pointer Receivers.
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
Three claims to test against the language, each executed-verified earlier:
No overriding: Admin embedding User with User's Greet — Admin gets Greet PROMOTED, but if Admin declares its own Greet, that's SHADOWING, not override: User's Greet still exists, still callable via a.User.Greet(), still what a User-typed variable calls. There's no dispatch layer where a User-typed value 'really' being an Admin behaves differently — Go values carry their type; the type decides the method, statically.
No subtype: an Admin is not a User — no assignment (var u User = admin fails; the promoted FIELDS don't make the types related), no 'is-a'. The relation is HAS-A (a User field) plus name promotion (syntax sugar over the field).
No virtual dispatch through receivers: method calls bind at compile time to the receiver's declared type. The ONLY runtime dispatch in Go is interfaces — the interface value carries (type, value), and the method call reads the type's itable. That mechanism belongs to interfaces, not receivers/embedding.
The positive framing — what Go gives instead: composition with promotion (reuse fields and methods, satisfy interfaces via promotion — the earlier embedded-AppStore demo), plus interfaces as the polymorphism mechanism (small, satisfied implicitly, resolved at runtime). The pair replaces inheritance's two jobs — reuse (embedding) and polymorphism (interfaces) — with orthogonal mechanisms that don't tangle: no fragile base (an embedded type's changes can't break an outer's override), no deep hierarchies (interfaces compose flat), and the type system stays decidable from local declarations.
The interview close: 'inheritance through receivers' is testing whether you know receivers are attachment, not a class system. The complete answer names embedding as the reuse mechanism, interfaces as the polymorphism mechanism, and states the deliberate split.
a := Admin{User: User{Name: "Root"}, Level: 9}
a.Greet() // promoted — but it's User's Greet, receiver is User
a.User.Greet() // same method, explicit path
// no vtable: both calls bind statically to User.Greetdebug a problem involving Value Vs Pointer Receivers
Direct Answer
No — receivers attach methods to one type; there's no overriding, no virtual dispatch, no subtype from receivers. Embedding promotes methods (reuse) but satisfies interfaces only through promotion — the embedded type's methods remain its own, statically bound.
Deep Dive & Architecture
Receivers sit between functions and types: a func with a receiver parameter is still a func — the receiver is sugar for an implicit first argument passed by value or by pointer, exactly like any other parameter. Method call u.Greet() compiles to a function call Greet(u) — the method expression User.Greet and the method value u.Greet make this equivalence explicit and usable. That is the whole mechanism — no vtable, no class metadata, no self type; just a function whose first parameter has special call syntax.
Contrast with virtual dispatch: a C++ method call through a pointer consults the object's vtable — the OBJECT's runtime type picks the implementation. Go's u.Greet() consults u's STATIC type's method set — compile-time, inlinable. The one Go construct with a table is the interface value: boxing copies (type, value) into the interface's two-word representation, and the interface's itable (built per interface-concrete pair at first assignment, cached) maps method names to function pointers. That itable is Go's vtable — but it belongs to the INTERFACE mechanism, not to receivers or embedding.
Embedding promotion is a compile-time rewrite: a.Greet() becomes a.User.Greet() — the wrapper forwards to the inner's method with the INNER as receiver. No dispatch decision happens. Interface satisfaction-through-promotion is the same rewrite applied to the method-set computation: the outer's method set gains a wrapper whose implementation is the inner's method.
The composition payoff: a change to User.Greet affects every embedder identically — as a change to a function they call, visible and versioned — never as a surprise override of hidden behavior. Fragile-base bugs require a dispatch layer that can diverge from what the author sees; Go has none. The cost is explicitness: when you WANT Admin-specific Greet, you write it, and the two methods coexist without ambiguity about which runs when — the receiver type decides, always.
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 Value Vs Pointer Receivers, and when would you use it?
- When would you use Value Vs Pointer Receivers in a real project?
- What is a common mistake when using Value Vs Pointer Receivers?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.