Ситуация у меня сейчас такая же, как был задан вопрос о том, в этой теме: Meaning of a struct with embedded anonymous interface?Перейти к отражению с интерфейсом, встроенным в структуру - как определить «реальные» функции?
type A interface {
Foo() string
}
type B struct {
A
bar string
}
идиоматически, исходя из фоном в ООП языках, что это выглядит, как этот шаблон «пытается сказать» мне заключается в том, что B должен реализовать интерфейс A. Но я до сих пор понимаю, что «Go отличается». Таким образом, вместо проверки времени компиляции я ожидал в первый, это счастливый скомпилировать с или без
func (B) Foo() string { .... }
настоящее время. Как упомянуто выше, вопрос (перефразируемый): «использование встроенных интерфейсов в структурах отлично подходит, когда вы только хотите реализовать/часть/интерфейса».
Предположительно, это связано с тем, что то, что происходит с этим встраиванием, точно так же, как и в каждом другом случае - значение типа B будет иметь значение анонимного интерфейса типа A в качестве поля. Лично, когда я нахожу, что ортогональность утешает, я также сбиваю с толку, что пакет отражения затем позволит мне получить методы A непосредственно из типа B таким образом, а не error/nil, если не существует метода с приемником B. Но - это вопрос не о мышлении за что - это о том, что значение интерфейса инициализируется после b := B{}
:
func main() {
bType := reflect.TypeOf(B{})
bMeth, has := bType.MethodByName("Foo")
if has {
fmt.Printf("HAS IT: %s\n",bMeth.Type.Kind())
res := bMeth.Func.Call([]reflect.Value{reflect.ValueOf(B{})})
val := res[0].Interface()
fmt.Println(val)
} else {
fmt.Println("DOESNT HAS IT")
}
}
Когда запускается, он вызывает ужасную панику
HAS IT: func
panic: runtime error: invalid memory address or nil pointer dereference
. .. или не - в зависимости от того, смог ли компилятор/время выполнения найти вышеуказанный метод. Итак: Как я могу обнаружить эту ситуацию до ее запуска?
То есть - есть ли что-то о значении bMeth, которое я могу использовать, чтобы увидеть, что нет реальной реализации в возвращаемых возвратом значениях метода и func? Точнее ли это что-то вроде «является указателем на функцию в таблице функций анонимного значения интерфейса в ноль» или что именно происходит с методами, которые вы извлекаете из интерфейса с отражением, где нет реализации?
Обертывание всей вещи в goroutine и попытка запустить функцию при отсрочке/панике - это не ответ - не только из-за расхода паники/отсрочки, но и потому, что функция вообще может, если она делает есть, есть побочные эффекты, которые я не хочу прямо сейчас ...
Я хочу что-то вроде реализации во время выполнения, которая отражает проверку типа компилятора? Или есть более простой способ? Я думаю об этом неправильно?
Above example in a Go playground
Тип 'B' имеет метод' Foo' - нет такой вещи, как «реальный» или «не настоящий» метод или функция.Вы можете либо взять эту информацию как есть, либо вы можете вызвать метод и посмотреть, что произойдет (для восстановления не требуется goroutine, просто отложенная функция). – JimB
Как я уже сказал, отложить/восстановить не вариант, потому что функция может существовать и иметь побочные эффекты. – BadZen
Тогда, если вы не собираетесь называть это, это имеет значение? Какую проблему вы пытаетесь решить, если знаете, что у типа есть метод, который вы не хотите вызывать? – JimB