Go har ingen arv — i stedet bruger det composition via struct embedding. Ved at indlejre en struct (eller interface) inde i en anden får den ydre type de indlejrede types felter og metoder direkte. Dette er Go svar på kode-genbrug, der foretrækker "har-en" composition frem for "er-en" arv.
Indlejring af en struct
type Animal struct {
Name string
}
func (a Animal) Eat() string {
return a.Name + " is eating"
}
type Dog struct {
Animal // EMBEDDED — no field name, just the type → composition
Breed string
}
d := Dog{
Animal: Animal{Name: "Rex"},
Breed: "Lab",
}
// Dog gets Animal's fields and methods PROMOTED — accessed directly
fmt.Println(d.Name) // "Rex" — promoted from the embedded Animal
fmt.Println(d.Eat()) // "Rex is eating" — Animal's method, called on Dog
Indlejring (skrivning af blot type-navnet, intet felt-navn) fremmer den indlejrede types felter og metoder til den ydre struct — så d.Name og d.Eat() virker, som om de tilhørte Dog. Dette ligner arv men er composition: Dog har en Animal.
Overriding af fremmet metoder
func (d Dog) Eat() string { // Dog defines its OWN Eat()
return d.Name + " the dog eats noisily"
}
d.Eat() // calls Dog's Eat (the outer one shadows the embedded one)
d.Animal.Eat() // explicitly call the embedded Animal's Eat if needed
Den ydre type kan definere en metode med samme navn for at "override" (skygge) den fremmet; du kan stadig nå den indlejrede version eksplicit.
Indlejring af interfaces (meget almindelig)
// embed interfaces to compose larger ones
type Reader interface { Read(p []byte) (int, error) }
type Writer interface { Write(p []byte) (int, error) }
type ReadWriter interface { // composed from both via embedding
Reader
Writer
}
// (this is exactly how io.ReadWriter is defined in the standard library)
Interface indlejring komponerer små interfaces til større — brugt hele standardbiblioteket.
Composition over arv — Go filosofien
No class hierarchies, no "extends". Instead:
✓ Embed to reuse fields/methods (has-a)
✓ Embed interfaces to compose behavior contracts
✓ Avoids the fragility, deep hierarchies, and tight coupling of inheritance
Hvorfor det betyder noget
Struct embedding er Go særegen mekanisme for kode-genbrug og composition, der erstatter arven som findes i de fleste OOP sprog.
At forstå det er væsentligt, fordi det er hvordan Go opnår genbrug (fremmer indlejrede felter/metoder så den ydre type "arver" adfærd gennem composition) og samtidig bevidst undgår arvens velkendte problemer (skrøbelige baseklasser, dybe stive hierarkier, stram koblinger).
Det inkarnerer det udbredt godkendt princip "composition over arv." Indlejring optræder konstant — indlejring af structs for genbrug, indlejring af interfaces for at bygge større kontrakter (som io.ReadWriter), og indlejring til mixin-stil adfærd.
At genkende at Go ikke har arv og at indlejring er dets compositional alternativ — plus metode-fremme og skygge reglerne — er fundamental for at læse og designe idiomatic Go, og et almindeligt interviewemne givet hvordan det adskiller sig fra klassebaserede sprog.
