Struct Embedding
#
// Go suporta _embedding_ ou _incorporação_ de structs e
// interfaces para expressar uma _composição_ de tipos
// que faça mais sentido.
// Não deve ser confundido com `//go:embed` que é uma diretiva de
// Go, introduzida na versão 1.16+ para incorporar arquivos e
// diretórios no binário de uma aplicação.
package main
import "fmt"
type base struct {
num int
}
func (b base) descrever() string {
return fmt.Sprintf("base com numero=%v", b.num)
}
// Uma struct `container` _incorpora_ a struct `base`.
// Uma incorporação é como um campo da struct, mas sem um nome.
type container struct {
base
str string
}
func main() {
// Ao criar structs com literais, é necessário inicializar
// a incorporação explicitamente; aqui, o tipo incorporado
// serve como nome do campo.
co := container{
base: base{
num: 1,
},
str: "algum nome",
}
// É possível acessar o campo da struct `base` diretamente
// na variável `co`, por exemplo com `co.num`.
fmt.Printf("co={num: %v, str: %v}\n", co.num, co.str)
// Alternativamente, pode ser acessado com o caminho completo
// usando o nome do tipo incorporado.
fmt.Println("outro número:", co.base.num)
// Como `container` incorpora `base`, os métodos de
// `base` também se tornam métodos do `container`.
// Aqui é invocado o método de `base` diretamente em `co`.
fmt.Println("descreva:", co.descrever())
type descritor interface {
descrever() string
}
// Structs incorporadas com métodos podem ser usadas para
// conceder implementações de interfaces em outras structs.
// Aqui é visto que um `container` agora implementa a
// interface `descritor` porque incorpora `base`.
var d descritor = co
fmt.Println("descritor:", d.descrever())
}
$ go run struct-embedding.go
co={numero: 1, str: algum nome}
outro número: 1
descreva: base com numero=1
descritor: base com numero=1