Skip to content

Тип reflect.Value и его значения

Точно так же мы можем создать reflect.Value значение из произвольного неинтерфейсного значения, вызвав функцию reflect.ValueOf. Значение результата reflect.Value представляет собой значение, не связанное с интерфейсом. Как и функция reflect.TypeOf, функция reflect.ValueOf также имеет только один параметр типа interface{}. Когда аргумент интерфейса передается вызову функции reflect.ValueOf, этот вызов возвращает reflect.Value значение, представляющее динамическое значение аргумента интерфейса. Чтобы получить reflect.Value значение, представляющее значение интерфейса, мы должны использовать косвенные способы.

Значение, представленное reflect.Value значением v, часто называют базовым значением v.

Для этого типа объявлено множество методов reflect.Value. Мы можем вызывать эти методы для проверки информации и манипулирования базовым значением значения reflect.Value получателя. Некоторые из этих методов применимы ко всем типам значений, некоторые из них специфичны для одного или нескольких видов. Пожалуйста, ознакомься с reflect документацией стандартного пакета для получения подробной информации. Вызов специфичного для вида метода с неправильным reflect.Value значением получателя вызовет панику.

Если ваше значение поддается изменению, мы можем вызвать Set метод соответствующего reflect.Value значения, чтобы изменить значение Go. Обрати внимание, что reflect.Value значения, возвращаемые непосредственно reflect.ValueOf вызовами функций, всегда доступны только для чтения.

Пример:

Неэкспортированные поля значений структуры не могут быть изменены с помощью рефлексии.

Из приведенных выше двух примеров мы понимаем, что есть два способа получить reflect.Value значение, на базовое значение которого ссылается базовое значение (значение указателя) другого reflect.Value значения.

  1. Один из способов — вызвать Elem метод reflect.Value значения, представляющего значение указателя.

  2. Другой способ — передать reflect.Value значение, представляющее значение указателя, reflect.Indirect вызову функции. Если аргумент, переданный reflect.Indirect вызову функции, не представляет значение указателя, вызов возвращает копию аргумента.

Обрати внимание, что этот reflect.Value.Elem метод также можно использовать для получения reflect.Value значения, представляющего динамическое значение значения интерфейса. Пример показан на скриншоте.

Стандартный reflect пакет также объявляет некоторые reflect.Value связанные функции. Каждая из этих функций соответствует встроенной функции или функции без рефлексии. В следующем примере показано, как связать (своего рода) пользовательскую универсальную функцию с различными значениями функции.

Если базовое значение reflect.Value является значением функции, то мы можем вызвать Call метод reflect.Value для вызова базовой функции.

Обратите внимание, что не экспортируемые поля не должны использоваться в качестве аргументов вызовов рефлексии. Если строку vt.FieldByName("A") в приведенном выше примере заменить на vt.FieldByName("b"), произойдет паника.