Метод reflect.Value.Addr

Метод reflect.Value.Addr возвращает новое значение типа reflect.Value, которое представляет собой указатель на значение, хранящееся в исходном reflect.Value. Этот метод полезен, когда необходимо получить доступ к адресу переменной для её последующего изменения через отражение. Важно: метод работает только с адресуемыми значениями, то есть с теми, которые могут быть изменены. Если вызвать метод на неадресуемом значении, возникнет паника.

Синтаксис

goreflect.Value.Addr()

Пример

Давайте получим указатель на значение переменной и изменим её через отражение:

gopackage main

import (
  "fmt"
  "reflect"
)

func main() {
  x := 42
  val := reflect.ValueOf(&x).Elem()
  ptr := val.Addr()
  ptr.Elem().SetInt(100)
  fmt.Println(x)
}

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

go100

Пример

Давайте получим указатель на поле структуры и изменим его значение:

gopackage main

import (
  "fmt"
  "reflect"
)

type User struct {
  Name string
  Age  int
}

func main() {
  user := User{Name: "John", Age: 30}
  val := reflect.ValueOf(&user).Elem()
  field := val.FieldByName("Age")
  ptr := field.Addr()
  ptr.Elem().SetInt(35)
  fmt.Println(user.Age)
}

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

go35

Пример

Попытка вызова метода на неадресуемом значении приведёт к панике:

gopackage main

import (
  "fmt"
  "reflect"
)

func main() {
  x := 42
  val := reflect.ValueOf(x)
  defer func() {
    if r := recover(); r != nil {
      fmt.Println("Panic:", r)
    }
  }()
  ptr := val.Addr()
  ptr.Elem().SetInt(100)
}

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

go"Panic: reflect.Value.Addr of unaddressable value"

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

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