What does this print? (no virtual dispatch with embedding)
Question 87HardGo 1.22 to 1.25
type Base struct{}
func (Base) Name() string { return "Base" }
func (b Base) Greet() string { return "Hello from " + b.Name() }
type Derived struct{ Base }
func (Derived) Name() string { return "Derived" }
func main() {
d := Derived{}
fmt.Println(d.Name()) // ?
fmt.Println(d.Greet()) // ?
}
Output:
Derived
Hello from Base
d.Name() resolves to Derived.Name, the shallowest method with that name. d.Greet() is promoted and becomes d.Base.Greet(). Inside Greet, b is a Base, and b.Name() is bound statically to Base.Name. Go has no vtable that lets an embedded type call "overridden" methods of the type that embeds it.
To get template-method behaviour, pass the behaviour in explicitly with an interface field or function:
type Namer interface{ Name() string }
func Greet(n Namer) string { return "Hello from " + n.Name() }
fmt.Println(Greet(Derived{})) // Hello from Derived
The interviewer is checking whether you carry OOP inheritance habits into Go.
More on Interfaces, Methods & Embedding
- Q85Explain type switch semantics. What does this print?
- Q86Is struct embedding inheritance? How does method promotion work?
- Q88Embedding
Tvs*T: how does each affect the method set of the outer struct? - Q89What happens when two embedded types provide the same field or method name?
- Q90What is interface embedding, and what changed in Go 1.14 about overlapping methods?
- Q91Why would you embed an interface inside a struct? What is the danger?