РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
463 of 1593 menu

Продвижение методов

Продвижение методов (method promotion) в Go — это механизм, позволяющий вызывать методы вложенной (анонимной) структуры непосредственно через экземпляр внешней структуры. Когда мы вкладываем одну структуру в другую как анонимное поле, все методы вложенной структуры становятся доступны и для внешней структуры.

Это похоже на наследование в ООП, но в Go это реализовано через композицию. Продвижение методов работает только для struct и interface, а также только в том случае, если поле является анонимным (без имени).

Синтаксис

type Inner struct { Value int } func (i Inner) Get() int { return i.Value } type Outer struct { Inner // анонимное поле }

Теперь методы Inner доступны через Outer.

Пример

Давайте создадим вложенную структуру User с методом GetName и внешнюю структуру Admin, которая будет иметь анонимное поле User:

package main import "fmt" type User struct { Name string } func (u User) GetName() string { return u.Name } type Admin struct { User Level int } func main() { admin := Admin{ User: User{Name: "Alice"}, Level: 5, } res := admin.GetName() fmt.Println(res) }

Результат выполнения кода:

"Alice"

Метод GetName был продвинут из структуры User в структуру Admin, и мы можем вызвать его напрямую через экземпляр Admin.

Пример

Если метод вложенной структуры принимает параметры, он также продвигается. Рассмотрим структуру Counter с методом Add:

package main import "fmt" type Counter struct { Count int } func (c *Counter) Add(n int) { c.Count += n } func (c Counter) Get() int { return c.Count } type ExtendedCounter struct { *Counter Name string } func main() { ec := ExtendedCounter{ Counter: &Counter{Count: 10}, Name: "MyCounter", } ec.Add(5) res := ec.Get() fmt.Println(res) }

Результат выполнения кода:

15

Методы Add и Get были продвинуты, и мы работаем с ними как с собственными методами структуры ExtendedCounter.

Пример

Если внешняя структура имеет метод с тем же именем, что и у вложенной, то метод внешней структуры переопределяет продвинутый метод. Проверим это на примере:

package main import "fmt" type Base struct { Value string } func (b Base) Get() string { return "Base: " + b.Value } type Wrapper struct { Base Value string } func (w Wrapper) Get() string { return "Wrapper: " + w.Value } func main() { w := Wrapper{ Base: Base{Value: "base"}, Value: "wrapper", } res := w.Get() fmt.Println(res) }

Результат выполнения кода:

"Wrapper: wrapper"

Метод Get структуры Wrapper переопределил продвинутый метод. Чтобы вызвать метод вложенной структуры, нужно обратиться к ней напрямую: w.Base.Get().

Смотрите также

Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить