Go поддържа влагане1 на структури и
взаимодействия, за да даде възможност за по-плавно
съставяне2 на структури и
взаимодействия. Това влагане следва да не се бърка с
директивата //go:embed, въведена в
издание 1.16 на Го, която се ползва за влагане на
файлове и папки в изпълнимия файл на приложението.
import "fmt"
type base struct {
num int
}
func (b base) describe() string {
return fmt.Sprintf(
"запис от основния вид с поле num=%v", b.num)
}
Вида container влага вид base. Влагането изглежда като поле без име. Пише се само вида.
type container struct {
base
str string
}
func main() {
Когато създаваме записи чрез буквални стойности на съставни (структурни) видове, трябва да наченем вложения вид изрично – да му дадем начална стойност. Тук вложения вид служи за име на полето.
co := container{
base: base{
num: 1,
},
str: "някакво име",
}
Можем да достъпим непосредствено полетата на
вложения вид направо от co така: co.num.
fmt.Printf("co={num: %v, str: %v}\n", co.num, co.str)
Но можем да изпишем и целия път, като упоменем и вложения вид структура.
fmt.Println("същото поле num:", co.base.num)
Понеже container влага в себе си base, методите
на base също стават методи на записите от вида
container. Тук извикваме метод, вложен от
base, направо върху записа co.
fmt.Println("извикваме describe:", co.describe())
type describer interface {
describe() string
}
Чрез влагането на структури можем „автоматично“ да
осъществяваме взаимодействия за влагащите съставни
видове. Тук виждаме, че сега променлива от
вида container осъществява describer понеже
base е вложен в container.
var d describer = co
fmt.Println("describer:", d.describe())
}
$ go run ./struct-embedding.go
co={num: 1, str: някакво име}
същото поле num: 1
извикваме describe: запис от основния вид с поле num=1
describer: запис от основния вид с поле num=1
Следващ пример: Обобщения.