I am trying to implement a method that changes the value of fields in an object that can have an arbitrary structure. The traversion of the fields is no problem when I have the pointer to a struct. But I can not manage to change the fields when I have an interface that does not wrap a pointer to a struct but the struct itself, in short:
// The following doesn't work
var x interface{} = A{Str: "Hello"}
// This panics: reflect: call of reflect.Value.Field on ptr Value
reflect.ValueOf(&x).Field(0).SetString("Bye")
// This panics: reflect: call of reflect.Value.Field on interface Value
reflect.ValueOf(&x).Elem().Field(0).SetString("Bye")
// This panics: reflect: reflect.Value.SetString using unaddressable value
reflect.ValueOf(&x).Elem().Elem().Field(0).SetString("Bye")
// This prints `false`. But I want this to be settable
fmt.Println(reflect.ValueOf(&x).Elem().Elem().Field(0).CanSet())
// This works
var z interface{} = &A{Str: "Hello"}
// This prints `true`
fmt.Println(reflect.ValueOf(z).Elem().Field(0).CanSet())
In long: http://play.golang.org/p/OsnCPvOx8F
I have read The Laws of Reflection so I am aware that I may only modify fields when I have a pointer to a struct. So my question is now: How do I get the pointer to the data of the struct?
UPDATE:
I got it working using basically y := reflect.New(reflect.TypeOf(x))
so the values of y
are settable now. For an extensive example see this: https://gist.github.com/hvoecking/10772475