Implicit Satisfaction
Fast recall
Quick revision
Core answer
Whether you understand Implicit Satisfaction 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
Go interfaces are satisfied implicitly. The type declares its methods; the interface declares its method list; if the type's method set contains all of the interface's methods, the type satisfies it — and the compiler verifies this at the assignment where you use the type as the interface.
type Reader interface{ Read() string }
type File struct{ name string }
func (f File) Read() string { return "reading " + f.name }
var r Reader = File{"a.txt"}
fmt.Println(r.Read())Executed. No declaration connects File to Reader — not at File's definition, not at Reader's, nowhere. The fit is verified where it's used, and only there.
What this buys: interfaces can be defined AFTER the types that satisfy them. You can write an interface for types in a package you don't own — sort.Interface over your type, io.Reader over anything with a Read. The dependency arrow points the useful direction: consumers define the interface they need; producers just have methods.
The standard library is built on this: io.Reader (one method) is satisfied by files, network connections, buffers, cipher streams, HTTP bodies, decompressors — most written without any reference to io.Reader. The interface came later, and the fit was discovered, not declared.
Implicit Satisfaction
Direct Answer
No 'implements' keyword — a type satisfies an interface by HAVING the methods. The check is structural: if File has Read() string, it satisfies interface{ Read() string }.
Deep Dive & Architecture
The mechanics of the compile-time check: interface satisfaction is decidable from method signatures alone. The compiler builds each named type's method set (name + signature pairs); an assignment var r Reader = x compiles iff Reader's method list is a subset of method-set(x). The failure error is precise: the missing method name(s), verbatim — 'File does not implement Reader (missing Read method)' — the diagnostic that teaches the rule.
What the check can't see, and why interface{} is different: an empty interface requires zero methods — every type satisfies it vacuously. That's why interface{} holds anything: the structural check on an empty set passes universally. It's also why interface{} carries no information about what the value can do. (Go 1.18's 'any' is a synonym — same semantics, shorter spelling.)
The duck-typing comparison and its precise boundary: Go is NOT runtime duck typing (Python — method presence checked at call time, failure at runtime). Go's check is compile-time and structural — full signature match, not just name match (a Read() int does not satisfy Read() string). The accurate framing: structural typing with static verification — the ergonomics of duck typing, the safety of a checked implements clause.
The design consequence for API authors: accept interfaces, return concrete types. The consumer can always narrow a concrete return to whatever interface they need; a producer accepting a concrete type forces the consumer to construct it. Accepting the interface (usually one method) lets callers pass anything that fits — the flexibility flows to the boundary where the requirements live.
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 Implicit Satisfaction in a real project?
- How would you compare Implicit Satisfaction with an alternative?
- What is a common mistake when using Implicit Satisfaction?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.