Type assertion f.(BC) успешен: динамический тип *Foo реализует B и C. Но программа не компилируется из-за y.A() и неиспользованной локальной переменной a.
Проверка возможности приведения одного интерфейса к другому в Go
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.