Я пытаюсь реализовать метод, который изменяет значение полей в объекте, который может иметь произвольную структуру. Трассировка полей не проблема, когда у меня есть указатель на структуру. Но я не могу изменить поля, когда у меня есть интерфейс, который не переносит указатель на структуру, а сама структура, короче:
// 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())
В длинном http://play.golang.org/p/OsnCPvOx8F
Я прочитал The Laws of Reflection, поэтому мне известно, что я могу изменять поля только тогда, когда у меня есть указатель на структуру. Итак, теперь мой вопрос: Как получить указатель на данные структуры?
UPDATE:
Я работал, используя в основном y := reflect.New(reflect.TypeOf(x))
, поэтому значения y
теперь можно настроить. Для подробного примера см. Это: https://gist.github.com/hvoecking/10772475