Senior
What is the difference between embedding and composition in Go?
sobes.tech AI
Answer from AI
In Go, embedding and composition are two ways of code reuse, but with different semantics and syntax.
Embedding:
- Allows including one type (struct or interface) into another without an explicit field.
- Embedded methods and fields become directly accessible through the outer type.
- This is similar to inheritance but without explicit inheritance.
Example:
type Logger struct {
Prefix string
}
func (l Logger) Log(msg string) {
fmt.Println(l.Prefix, msg)
}
// Embedding Logger into App
type App struct {
Logger
Name string
}
app := App{Logger: Logger{Prefix: "[App]"}, Name: "MyApp"}
app.Log("started") // can be called directly
Composition:
- Means that a struct contains another field with a type, but access to methods/fields occurs through this field.
- No automatic promotion of methods to the outer type.
- A more explicit and controlled way of combining functionality.
Example:
type Engine struct {
Power int
}
func (e Engine) Start() {
fmt.Println("Engine started with power", e.Power)
}
// Composition of Engine into Car
type Car struct {
engine Engine
Model string
}
car := Car{engine: Engine{Power: 100}, Model: "Sedan"}
car.engine.Start() // need to explicitly access the field
Key differences:
- Embedding simplifies access to methods and fields of the embedded type, making them part of the outer type.
- Composition requires explicit access to the nested field.
- Embedding is often used for implementing interfaces and extending functionality.
Thus, embedding is syntactic sugar for composition with automatic promotion of methods and fields.