2

I try to set value to a struct field (pointer field) by reflect, but failed.

  1. I get the name of a struct field, so use FieldByName to get the field
  2. The field is a pointer.
  3. I try to use FieldByName().Set FieldByName().SetPointer to set value.
type t struct {
    b *int
}

func main() {
    t := new(ts)
    a := new(int)
    ss := reflect.ValueOf(t).FieldByName("b").Set(a)
}
type t struct {
    b *int
}

func main() {
    t := new(ts)
    a := new(int)
    ss := reflect.ValueOf(t).FieldByName("b").SetPointer(a)
}

First code: =======> ./test.go:14:50: cannot use a (type *int) as type reflect.Value in argument to reflect.ValueOf(t).FieldByName("b").Set ./test.go:14:50: reflect.ValueOf(t).FieldByName("b").Set(a) used as value

Second code: =======> ./test.go:14:57: cannot use a (type *int) as type unsafe.Pointer in argument to reflect.ValueOf(t).FieldByName("b").SetPointer ./test.go:14:57: reflect.ValueOf(t).FieldByName("b").SetPointer(a) used as value

I want to use reflect to make the pointer field (name "b") alloced a space and set a value.

wusuoweimain
  • 21
  • 1
  • 2

1 Answers1

6
type ts struct {
    B *int    //field must be exported
}

func main() {
    var t ts
    foo := 5
    a := &foo
    //Use Elem() to indirect through the pointer and get struct field
    //Use reflect.ValueOf(a) to satisfy Set() signature
    reflect.ValueOf(&t).Elem().FieldByName("B").Set(reflect.ValueOf(a))
    fmt.Println(*t.B)
}

Playground https://play.golang.org/p/gZt0ahTZMIi

Uvelichitel
  • 8,220
  • 1
  • 19
  • 36
  • Just FYI, `Elem` does not "achieve setability", calling Elem on a non-settable value will not make it settable. Instead, in this case, Elem returns the `reflect.Value` representation of the *struct* value pointed to by `&t`. This is necessary because calling `FieldByName` on a `reflect.Value` representation of a *pointer* will panic since pointers do not have fields. – mkopriva Jul 22 '19 at 15:41