Go by Example: Struct Embedding

Go soporta la incrustación de estructuras (structs) e interfaces para expresar una composición más fluida de tipos. Esto no debe confundirse con embed-directive, que es una directiva de Go introducida en la versión 1.16+ para incrustar archivos y carpetas en el binario de la aplicación.

package main
import "fmt"
type base struct {
    num int
}
func (b base) describe() string {
    return fmt.Sprintf("base with num=%v", b.num)
}

Un container incrusta un base. Una incrustación parece ser un campo sin nombre.

type container struct {
    base
    str string
}
func main() {

Al crear estructuras con literales, tenemos que inicializar la incrustación explícitamente; aquí el tipo incrustado sirve como nombre del campo.

    co := container{
        base: base{
            num: 1,
        },
        str: "some name",
    }

Podemos acceder a los campos de base directamente en co, por ejemplo, co.num.

    fmt.Printf("co={num: %v, str: %v}\n", co.num, co.str)

Alternativamente, podemos especificar la ruta completa utilizando el nombre del tipo incrustado.

    fmt.Println("also num:", co.base.num)

Ya que container incrusta base, los métodos de base también se convierten en métodos de container. Aquí invocamos un método que fue incrustado de base directamente en co.

    fmt.Println("describe:", co.describe())
    type describer interface {
        describe() string
    }

Incrustar estructuras con métodos puede usarse para otorgar implementaciones de interfaces a otras estructuras. Aquí vemos que un container ahora implementa la interfaz describer porque incrusta base.

    var d describer = co
    fmt.Println("describer:", d.describe())
}
$ go run struct-embedding.go
co={num: 1, str: some name}
also num: 1
describe: base with num=1
describer: base with num=1

Siguiente ejemplo: Generics.