Вы можете использовать функцию 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()
, сравнивая результат с 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 см. Сообщение в блоге: The Laws of Reflection.
Точно, как я хотел бы получить ответ! Благодарим вас за дополнительную милю и предоставим рабочий код. – RAFJR
Благодарим вас за подробный ответ, включая сообщение в блоге. Очень полезно. –