Как выполнить итерацию функций * T из struct over refle.TypeOf (interface {})? - PullRequest
2 голосов
/ 29 марта 2019

У меня возникли некоторые проблемы при переборе *T funcs из struct с использованием reflect.

Я искал много ответов, но, похоже, никто не говорил конкретно об этой ситуации.

Я нашел reflect.NewAt в документации по golang, но, честно говоря, я не понял, и снова я не смог найти ни одного ответа для моей ситуации.

Для лучшего понимания ... имея следующую структуру:

type Counter struct {}
func (self *Counter) Add(n int) {}

Если я использую отражение, вызывая сам указатель структуры, он работает как ожидалось:

y := reflect.TypeOf(&Counter{})

for k := 0; k < y.NumMethod(); k++ {
    fmt.Println(y.Method(k)) // {Add  func(*Counter, int) <func(*Counter, int) Value> 0}
}

Но в моём случае сюда может прийти несколько структур, поэтому он поступает как интерфейс:

var p interface{} = Counter{}

z := reflect.New(reflect.TypeOf(p))

for k := 0; k < z.NumMethod(); k++ {
   fmt.Println(z.Method(k)) // 0x47d150
}

Но, как показано, он печатает адрес памяти.

Я ожидаю, что 0x47d150 будет таким же выводом, как я использовал указатель напрямую. Что я тут не так делаю?

1 Ответ

3 голосов
/ 29 марта 2019

Значение y a reflect.Type. Метод Method для типа является эквивалентом выражения метода .

Значение z представляет собой reflect.Value. Метод Method для значения является эквивалентом значения метода .

Печатное представление отличается, потому что выражения метода и значения метода не одно и то же.

Используйте reflect.PtrTo, чтобы получить тип указателя для типа:

var p interface{} = Counter{}
z := reflect.PtrTo(reflect.TypeOf(p))
for k := 0; k < z.NumMethod(); k++ {
    fmt.Println(z.Method(k))  // {Add  func(*Counter, int) <func(*Counter, int) Value> 0}
}

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

var p interface{} = &Counter{}
z := reflect.TypeOf(p)
for k := 0; k < z.NumMethod(); k++ {
    fmt.Println(z.Method(k)) // {Add  func(*Counter, int) <func(*Counter, int) Value> 0}
}
...