patterngoModeratepending
Go struct embedding and interface satisfaction
Viewed 0 times
struct embeddinginterfacecompositionpromotionmiddleware
Problem
Need to compose behaviors in Go without inheritance, and understand how embedding satisfies interfaces.
Solution
Go struct embedding promotes fields and methods:
Rules:
// Base logger
type Logger struct{}
func (l Logger) Log(msg string) { fmt.Println(msg) }
// Embed Logger in Service
type Service struct {
Logger // Embedded - promotes Log method
Name string
}
s := Service{Name: "auth"}
s.Log("started") // Promoted from Logger
// Interface satisfaction through embedding
type Loggable interface {
Log(string)
}
var _ Loggable = Service{} // Service satisfies Loggable via embedding
// Practical: HTTP middleware with embedded handler
type AuthMiddleware struct {
http.Handler // Embed the interface
Token string
}
func (a AuthMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") != a.Token {
http.Error(w, "unauthorized", 401)
return
}
a.Handler.ServeHTTP(w, r) // Delegate to embedded handler
}
// Multiple embedding
type ReadWriteCloser struct {
io.Reader
io.Writer
io.Closer
}Rules:
- Embedded type's methods are promoted to the outer struct
- If two embedded types have same method, must resolve ambiguity explicitly
- Embedding is composition, not inheritance
Why
Embedding is Go's mechanism for code reuse without inheritance. It provides clean composition while automatically satisfying interfaces.
Gotchas
- Ambiguous methods from multiple embeddings must be resolved
- Embedded struct's methods receive the embedded struct as receiver, not the outer struct
Context
Go code design using composition instead of inheritance
Revisions (0)
No revisions yet.