#go #reflection #struct #reply
#Вперед #отражение #структура #Ответить
Вопрос:
Как мне узнать, к каким полям я могу получить доступ из reply
объекта / интерфейса? Я попробовал отражение, но, похоже, сначала вам нужно знать имя поля. Что, если мне нужно знать все доступные мне поля?
// Do sends a command to the server and returns the received reply.
Do(commandName string, args ...interface{}) (reply interface{}, err error)
Ответ №1:
Вы можете использовать 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("% vn", 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
значение, которое является a 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.
Примечание: часто указатель на struct заключен в интерфейс. В таких случаях вы можете использовать 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.
Для подробного ознакомления с отражением Go прочитайте сообщение в блоге: Законы отражения.