Переопределение метода Go

Рейтинг: 0Ответов: 1Опубликовано: 04.02.2023

У меня есть структура с большим количеством методов. Мне нужно переписать для другой структуры 1 метод. В цепочке вызовов методов, метод, который нужно переписать, находится в середине. Как мне это реализовать?

Вот пример чего у меня не получается, встроенный в структуру B метод caller() работает, но вызывает метод print() не из B, а из A:

type A struct{}

func (a *A) caller() {
    a.print()
}

func (a *A) print() {
    fmt.Println("a print")
}

type B struct {
    A
}

func (b *B) print() {
    fmt.Println("b print")
}

func main() {
    var b B
    b.caller()
}

Ответы

▲ 3Принят

Почему ваш пример не работает.

Поле без имени на самом деле означает неявное поле с именем, совпадающем с именем типа. То есть

type B struct {
    A
}

почти равнозначно

type B struct {
    A A
}

Единственная разница в том, что при использовании поля без имени методы такого поля можно вызывать без указания имени поля. То есть в вашем коде вызов b.caller() - это сокращение для b.A.caller(). Ничего удивительного, что b.A.caller() вызывает b.A.print(), а не ваш переопределённый B.print()

Почему в Go нельзя "переопределить" метод.

Go - язык со статической типизацией, то есть все вызовы определяются на этапе компиляции. То, что нужно вам, называется виртуальным методом, который разрешается на этапе выполнения. В Go такие фокусы запрещены.