In Go ist Embedding der Mechanismus, der es ermöglicht, das Verhalten einer Struktur durch das Einbetten einer Struktur in eine andere zu "erben", ohne eine explizite Vererbung zu verwenden, wie zum Beispiel in der OOP. Die eingebettete Struktur wird zu den Feldern der neuen Struktur (anonyme Felder).
Dabei werden alle Methoden der eingebetteten Struktur zu den Methoden der neuen Struktur, als ob sie "vererbt" wurden.
Beispiel:
package main import "fmt" type Animal struct { Name string } func (a Animal) Speak() { fmt.Println("Mein Name ist", a.Name) } type Dog struct { Animal // Einbettung, anonymes Feld Breed string } func main() { d := Dog{ Animal: Animal{Name: "Rex"}, Breed: "Shepherd", } d.Speak() // Vererbte Methode! fmt.Println(d.Name) // Feld direkt verfügbar }
Der Hauptunterschied zwischen Einbettung und normaler Einfügung einer Struktur als benanntem Feld:
"Wenn die eingebettete Struktur und die äußere Felder mit demselben Namen enthalten, welches wird verwendet und wie kann man darauf zugreifen?"
Viele glauben, dass nur das "obere" Feld verwendet wird, aber es funktioniert anders:
Beispiel:
type Base struct { Name string } type Child struct { Base // Einbettung Name string // übereinstimmendes Feld } c := Child{Base: Base{Name: "Base"}, Name: "Child"} fmt.Println(c.Name) // Child fmt.Println(c.Base.Name) // Base
Geschichte
In einem Projekt wurde eine Standardstruktur für das Logging eingebettet, und anschließend wurde ein Feld
Loggerim Kindtyp definiert. Infolgedessen funktionierten Aufrufe wied.Logger.Info()nicht wie erwartet, da der Zugriff auf das eingebettete Feld "verloren ging" zwischen den gleichnamigen.
Geschichte
Der Entwickler versuchte, eine Methode in der Kindstruktur zu überschreiben, aber Methoden werden nicht "überschrieben" – es erscheint einfach eine neue, und die Elternmethode bleibt weiterhin über
Child.Base.Method()verfügbar. Dies führte dazu, dass ein Teil des Codes die "alte" Version der Methode verwendete, wobei eine andere Logik erwartet wurde.
Geschichte
Bei der Serialisierung von JSON mit eingebetteten Strukturen gab es Überraschungen: Die Felder der "eingebetteten" Struktur tauchten im Stammobjekt auf. Aufgrund mangelnden Wissens über die Auswirkungen von Einbettung auf das Marshaling wurde die Struktur inkorrekt serialisiert, was die Abwärtskompatibilität der API beeinträchtigte.