На этом шаге рассмотрим использование встраиваемых полей в Go.
Составные типы на основе структур могут включать один или более типов (в том числе и интерфейсы) в виде встраиваемых полей. Главное удобство такого подхода заключается в возможности вызывать методы встроенного типа относительно значения пользовательского типа, как если бы они были собственными методами этого типа, при этом в качестве приемников таким методам будут передаваться встроенные поля.
type Item struct { id string // Именованное поле (агрегирование) price float64 // Именованное поле (агрегирование) quantity int // Именованное поле (агрегирование) } func (item *Item) Cost() float64 { return item.price * float64(item.quantity) } type SpecialItem struct { Item // Анонимное поле (встраивание) catalogId int // Именованное поле (агрегирование) }
Здесь тип SpecialItem встраивает тип Item. Это означает, что относительно значения типа SpecialItem можно вызвать метод Cost(), принадлежащий типу Item.
special := SpecialItem{Item{"Синий", 3, 5}, 207} fmt.Println(special.id, special.price, special.quantity, special.catalogId) fmt.Println(special.Cost())
Вызов special.Cost() компилятор Go будет интерпретировать как вызов метода Item.Cost(), потому что тип SpecialItem не имеет собственного метода Cost(), и передаст ему встроенное значение типа Item, а не все значение типа SpecialItem, относительно которого метод вызывался первоначально.
Если имя какого-либо поля во встроенном типе Item совпадает с именем поля в типе SpecialItem, обратиться к полю во встроенном типе Item можно, указав имя типа как часть полного имени поля, например special.Item.price.
Архив с примерами можно взять здесь.
На следующем шаге рассмотрим способ переопределения методов встраиваемых полей в Go.