#go
#Вперед
Вопрос:
Нужна помощь в понимании того, почему это ломается. PrintFoo можно вызвать, используя либо указатель, либо значение. Почему не NumField?
http://play.golang.org/p/Kw16ReujRx
type A struct {
foo string
}
func (a *A) PrintFoo(){
fmt.Println("Foo value is " a.foo)
}
func main() {
a := amp;A{foo: "afoo"}
(*a).PrintFoo() //Works - no problem
a.PrintFoo() //Works - no problem
reflect.TypeOf(*a).NumField() //Works - no problem - Type = main.A
reflect.TypeOf(a).NumField() //BREAKS! - Type = *main.A
}
Ответ №1:
Из документации :
// NumField returns the number of fields in the struct v.
// It panics if v's Kind is not Struct.
func (v Value) NumField() int
Вы вызываете его по указателю, вместо этого вы должны вызвать его в структуре, например :
fmt.Println(reflect.Indirect(reflect.ValueOf(a)).NumField())
fmt.Println(reflect.Indirect(reflect.ValueOf(*a)).NumField())
Если вы не уверены, является ли ваше значение указателем или нет, используйте reflect .Косвенный:
Косвенный возвращает значение, на которое указывает v . Если v — нулевой указатель, Indirect возвращает нулевое значение. Если v не является указателем, косвенный возвращает v.
//править:
NumField
вызывается Value
, а не ваш фактический объект, например, вы делаете:
func main() {
a := amp;A{foo: "afoo"}
fmt.Printf("%#vn", reflect.TypeOf(*a))
fmt.Printf("%#vn", reflect.TypeOf(a))
}
Вы получите :
//*a
amp;reflect.rtype{size:0x8, ...... ptrToThis:(*reflect.rtype)(0xec320)}
//a
amp;reflect.rtype{size:0x4, ...... ptrToThis:(*reflect.rtype)(nil)}
Как вы можете сказать, это совершенно другой зверь.
- Первый содержит информацию об указателе, следовательно
ptrToThis
, указывает на фактическую структуру. - Второй содержит информацию о самой структуре.
Комментарии:
1. >> «Вы вызываете его по указателю, вместо этого вы должны вызывать его в структуре» — Но я смог вызвать PrintFoo с помощью pointer или struct . Это сработало в любом случае. Почему не с NumField меня сбило с толку.
2. Вы не вызываете
NumField
a
, вы вызываете его, несмотря ни наtype Value struct{}
что, вашa
может быть float или string , но пока это не «прямая» структура, это приведет к ошибке.3. Добавьте больше информации, я надеюсь, это поможет.