Вы можете использовать функцию reflect.TypeOf()
для получения reflect.Type
дескриптор типа. Оттуда вы можете перечислить поля динамического значения, хранящиеся в интерфейсе.
Пример:
type Point struct {
X int
Y int
}
var reply interface{} = Point{1, 2}
t := reflect.TypeOf(reply)
for i := 0; i < t.NumField(); i++ {
fmt.Printf("%+v\n", t.Field(i))
}
Выход:
{Name:X PkgPath: Type:int Tag: Offset:0 Index:[0] Anonymous:false}
{Name:Y PkgPath: Type:int Tag: Offset:4 Index:[1] Anonymous:false}
Результатом вызова Type.Field()
является значение reflect.StructField
, представляющее собой struct
, содержащее имя поле среди прочего:
type StructField struct {
// Name is the field name.
Name string
// ...
}
Если вам также нужны значения полей, вы можете использовать reflect.ValueOf()
для получения reflect.Value()
, а затем вы можете использовать Value.Field()
или Value.FieldByName()
:
v := reflect.ValueOf(reply)
for i := 0; i < v.NumField(); i++ {
fmt.Println(v.Field(i))
}
Выход:
1
2
Попробуйте его на Go Playground.
Примечание: часто указатель на структуру заворачивается в интерфейс. В таких случаях вы можете использовать Type.Elem()
и Value.Elem()
для "перехода" к указанному типу или ценность:
t := reflect.TypeOf(reply).Elem()
v := reflect.ValueOf(reply).Elem()
Если вы не знаете, указатель это или нет, вы можете проверить это с помощью Type.Kind()
и Value.Kind()
< /a>, сравнивая результат с reflect.Ptr
:
t := reflect.TypeOf(reply)
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
// ...
v := reflect.ValueOf(reply)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
Попробуйте этот вариант на Go Playground.
Подробное введение в рефлексию Go можно найти в записи блога: Законы рефлексии.
person
icza
schedule
05.10.2016