Получить имя поля структуры с использованием отражения
Какой способ печати "Foo" здесь? В этом примере то, что печатает, является "строкой".
http://play.golang.org/p/ZnK6PRwEPp
type A struct {
Foo string
}
func (a *A) PrintFoo() {
fmt.Println("Foo value is " + a.Foo)
}
func main() {
a := &A{Foo: "afoo"}
val := reflect.Indirect(reflect.ValueOf(a))
fmt.Println(val.Field(0).Type().Name())
}
Ответы
Ответ 1
Вы хотите val.Type().Field(0).Name
. Метод Field
на reflect.Type
будет возвращать структуру, описывающую это поле, которое включает имя, среди другой информации.
Невозможно получить имя поля для reflect.Value
, представляющего конкретное значение поля, поскольку это свойство содержащей struct.
Ответ 2
Вам нужно получить поле определения типа, а не значения.
http://play.golang.org/p/7Bc7MJikbJ
package main
import "fmt"
import "reflect"
type A struct {
Foo string
}
func (a *A) PrintFoo() {
fmt.Println("Foo value is " + a.Foo)
}
func main() {
a := &A{Foo: "afoo"}
val := reflect.Indirect(reflect.ValueOf(a))
fmt.Println(val.Type().Field(0).Name)
}
Ответ 3
С новым Names
методом structs пакет еще проще:
package main
import (
"fmt"
"github.com/fatih/structs"
)
type A struct {
Foo string
Bar int
}
func main() {
names := structs.Names(&A{})
fmt.Println(names) // ["Foo", "Bar"]
}
Ответ 4
Я думаю, что лучший способ получить имя поля в структуре
func main() {
a := &A{Foo: "afoo"}
val := reflect.ValueOf(a).Elem()
for i:=0; i<val.NumField();i++{
fmt.Println(val.Type().Field(i).Name)
}
}
Есть два совета:
- используйте
.Elem()
после reflect.ValueOf(a)
, потому что в вашем случае a является указателем. -
val.Field(i).Type().Name
полностью отличается от val.Type().Field(i).Name
. Последний может получить имя поля в структуре
Надеюсь, что это полезно..
Если вы хотите посмотреть больше случаев, пожалуйста, проверьте мою статью за 2 минуты
Ответ 5
Вы также можете использовать https://github.com/fatih/structs
// Convert the fields of a struct to a []*Field
fields := s.Fields()
for _, f := range fields {
fmt.Printf("field name: %+v\n", f.Name())
}
Ответ 6
package main
import "fmt"
import "reflect"
type A struct {
Foo string
}
func (a *A) PrintFoo() {
fmt.Println("Foo value is " + a.Foo)
}
func main() {
a := &A{Foo: "afoo"}
//long and bored code
t := reflect.TypeOf(*a)
if t.Kind() == reflect.Struct {
for i := 0; i < t.NumField(); i++ {
fmt.Println(t.Field(i).Name)
}
} else {
fmt.Println("not a stuct")
}
//shorthanded call
fmt.Println(reflect.TypeOf(*a).Field(0).Name)//can panic if no field exists
}