Почему typeof (метод) не возвращает отражающий экземпляр .Method? - PullRequest
2 голосов
/ 15 мая 2019

Допустим, у меня есть структура Foo с методом, определенным следующим образом:

type Foo struct {
    Name string
}

func (f *Foo) Get(a int, b string) (string, error) {
    return f.Name, nil
}

Если я напишу

obj := &Foo{}
t := reflect.TypeOf(obj.Get)

t.Kind() возвращает reflect.Func и, по-видимому, у меня нет возможности получить доступ к информации, что Get func Я извлек информацию о типе из "принадлежит" к структуре Foo, то есть получатель имеет тип Foo, это даже не отображается в параметрах.

Полагаю, это намеренно, и я упускаю что-то фундаментальное в функциях, из-за которых авторы языка отбрасывают информацию о приемнике для операций typeof, применяемых к ссылкам на методы.

У меня есть два вопроса:

  1. Правильно ли я и нет способа получить тип получателя во фрагменте с TypeOf вызов выше?
  2. Какие у меня есть альтернативы, если я хочу передать информацию об отражении метода в некоторый код, который предназначен для анализа функции и связанного получателя (то есть, по сути, метода)?

Пытаясь ответить на второй вопрос самостоятельно, и исходя из того, что я вижу в официальной документации, похоже, что мои единственные варианты - либо передать TypeOf (получатель) и TypeOf (получатель.метод), либо TypeOf (получатель) и имя метод получателя.

1 Ответ

5 голосов
/ 15 мая 2019

Как упомянул mkopriva, у вас есть значение метода : obj.Get.И значение метода является функцией, чья сигнатура идентична методу без типа получателя:

Если выражение x имеет статический тип T и M находится в набор методов типа T, x.M называется значением метода .Значение метода x.M является значением функции, которое можно вызывать с такими же аргументами, что и вызов метода x.M.Выражение x вычисляется и сохраняется во время оценки значения метода;Сохраненная копия затем используется в качестве получателя в любых вызовах, которые могут быть выполнены позже.

Если вы используете выражение метода (вместо значения метода), получательтип «отображается» в списке параметров (он всегда первый):

fmt.Println(reflect.TypeOf((*Foo).Get))

Выходы (попробуйте на Go Playground ):

func(*main.Foo, int, string) (string, error)

Выражение метода:

Если M находится в наборе методов типа T, T.M - это функция, которая вызывается как обычная функция с тем жеаргументы как M с префиксом дополнительного аргумента, который является получателем метода .

См. связанные вопросы:

golang - pass методдля работы

псевдоним функции Голанга на приемнике метода

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...