En Go, el embedding (inclusión) es un mecanismo que permite "heredar" el comportamiento de una estructura al incluir una estructura dentro de otra sin el uso de la herencia explícita, como en OOP. La estructura incluida se convierte en un campo-anónimo de la nueva estructura.
En este caso, todos los métodos de la estructura incluida se convierten en métodos de la nueva estructura, como si se "heredaran".
Ejemplo:
package main import "fmt" type Animal struct { Name string } func (a Animal) Speak() { fmt.Println("My name is", a.Name) } type Dog struct { Animal // embedding, campo anónimo Breed string } func main() { d := Dog{ Animal: Animal{Name: "Rex"}, Breed: "Shepherd", } d.Speak() // ¡Método heredado! fmt.Println(d.Name) // Campo accesible directamente }
La principal diferencia entre la inclusión y la inclusión normal de una estructura como campo nombrado es:
"Si la estructura incluida y la externa contienen campos con los mismos nombres, ¿cuál se utilizará y cómo se accederá a ellos?"
Muchos creen que solo se usará el campo "superior", pero funciona de otra manera:
Ejemplo:
type Base struct { Name string } type Child struct { Base // embedding Name string // campo coincidente } c := Child{Base: Base{Name: "Base"}, Name: "Child"} fmt.Println(c.Name) // Child fmt.Println(c.Base.Name) // Base
Historia
En el proyecto se incluyó una estructura estándar para registros, y luego se definió el campo
Loggeren el tipo hijo. Como resultado, las llamadasd.Logger.Info()no funcionaban como se esperaba, ya que el acceso al campo incluido se "perdía" entre los de nombre similar.
Historia
El desarrollador intentaba sobrescribir un método en la estructura hija, pero los métodos no se "sobrescriben"; simplemente aparece uno nuevo, y el padre sigue estando disponible como
Child.Base.Method(). Esto llevó a que parte del código usara la "antigua" versión del método, esperando otra lógica.
Historia
Al serializar JSON con estructuras anidadas, surgieron sorpresas: los campos de la estructura "incluida" aparecían en el objeto raíz. Debido a la falta de conocimiento sobre cómo la inclusión afecta al marshaling, la estructura se serializaba incorrectamente, rompiendo la compatibilidad con versiones anteriores de la API.