Проверка возможности приведения одного интерфейса к другому в Go

Type assertion f.(BC) успешен: динамический тип *Foo реализует B и C. Но программа не компилируется из-за y.A() и неиспользованной локальной переменной a.

Короткий ответ

Что ответить на собеседовании

Type assertion f.(BC) успешен: динамический тип *Foo реализует B и C. Но программа не компилируется из-за y.A() и неиспользованной локальной переменной a.

Подробный разбор

Ответ с пояснениями

Условие

Нужно понять, какой результат получит программа. Вопрос: допустимо ли выполнить type assertion от одного интерфейса к другому и приведёт ли это к панике во время выполнения или же методы будут успешно вызваны.

type Foo struct{}

func (f *Foo) A() {}
func (f *Foo) B() {}
func (f *Foo) C() {}

type AB interface {
  A()
  B()
}

type BC interface {
  B()
  C()
}

func main() {
  var a int
  var f AB = &Foo{}
  y := f.(BC) // сработает ли такой type-assertion?
  y.A()       // а этот вызов?
  _ = y
}

Ответ

Type assertion f.(BC) успешен: динамический тип *Foo реализует B и C. Но программа не компилируется из-за y.A() и неиспользованной локальной переменной a.

Статический тип y — BC, в его наборе методов нет A, даже если динамическое значение этот метод имеет. Можно вызвать f.A(), расширить интерфейс или явно проверить нужный дополнительный контракт. Удалите a либо используйте её. Для assertion с неизвестным динамическим типом применяйте форму y, ok := f.(BC), чтобы обработать несовпадение без panic.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее