Метод reflect.Value.Interface

Метод Interface, вызванный на значении типа reflect.Value, возвращает исходное значение, которое было положено в отражение, в виде пустого интерфейса (interface{}). Этот метод является мостом между миром рефлексии и обычным миром типов Go. Он позволяет преобразовать отраженное значение обратно в значение конкретного типа с помощью утверждения типа (type assertion). Важно понимать, что метод возвращает именно динамическое значение, а не само отражение.

Синтаксис

gofunc (v Value) Interface() interface{}

Пример

Давайте создадим переменную типа int, получим ее отражение с помощью reflect.ValueOf, а затем извлечем исходное значение с помощью метода Interface:

gopackage main

import (
  "fmt"
  "reflect"
)

func main() {
  num := 42
  val := reflect.ValueOf(num)
  res := val.Interface()
  fmt.Println(res)
}

Результат выполнения кода:

go42

Пример

Чтобы работать с извлеченным значением как с конкретным типом, необходимо использовать утверждение типа. Например, получим строку из отражения:

gopackage main

import (
  "fmt"
  "reflect"
)

func main() {
  str := "abcde"
  val := reflect.ValueOf(str)
  interfaceVal := val.Interface()
  res, ok := interfaceVal.(string)
  if ok {
    fmt.Println(res)
  }
}

Результат выполнения кода:

go"abcde"

Пример

Метод Interface также работает со слайсами и другими составными типами. Извлечем слайс строк из отражения:

gopackage main

import (
  "fmt"
  "reflect"
)

func main() {
  slice := []string{"a", "b", "c", "d", "e"}
  val := reflect.ValueOf(slice)
  interfaceVal := val.Interface()
  res, ok := interfaceVal.([]string)
  if ok {
    fmt.Println(res)
  }
}

Результат выполнения кода:

go[a b c d e]

Пример

Важно помнить, что метод Interface паникует, если значение reflect.Value не может быть безопасно преобразовано в интерфейс (например, если оно представляет неэкспортируемое поле структуры). Для проверки доступности используйте метод CanInterface:

gopackage main

import (
  "fmt"
  "reflect"
)

type User struct {
  name string
  age  int
}

func main() {
  u := User{name: "Alice", age: 30}
  val := reflect.ValueOf(u)
  field := val.FieldByName("name")
  if field.CanInterface() {
    res := field.Interface()
    fmt.Println(res)
  } else {
    fmt.Println("field is unexported")
  }
}

Результат выполнения кода:

go"field is unexported"

Смотрите также

  • функцию reflect.ValueOf,
    которая создает отражение из обычного значения
  • метод reflect.Value.Kind,
    который возвращает базовый вид значения
  • метод reflect.Value.CanInterface,
    который проверяет, можно ли вызвать Interface без паники
  • метод reflect.Value.Type,
    который возвращает тип отраженного значения