According to The Laws of Reflection it is not possible to set the value of an element as follows, you need to use its address.
This will not work:
var x float64 = 3.4
v := reflect.ValueOf(x)
v.SetFloat(7.1) // Error: will panic.
This will work:
var x float64 = 3.4
p := reflect.ValueOf(&x) // Note: take the address of x.
p.Elem().SetFloat(7.1)
So why will the following work when using slices?
floats := []float64{3}
v := reflect.ValueOf(floats)
e := v.Index(0)
e.SetFloat(6)
fmt.Println(floats) // prints [6]
http://play.golang.org/p/BWLuq-3m85
Surely v.Index(0)
is taking the value instead of address from slice floats
, thus meaning it shouldn't be settable like the first example.
In your first example, you pass the actual x
. This will copy x
and give it to reflect.ValueOf
. When you try to do v.SetFloat
, as it get only a copy, it has no way to change the original x
variable.
In your second example, you pass the address of x
, so you can access the original variable by dereferencing it.
In the third example, you pass floats
to reflect.ValueOf
, which is a slice. "Slice hold references to the underlying array" (http://golang.org/doc/effective_go.html#slices). Which mean that through the slice, you actually have a reference to the underlying object. You won't be able to change the slice itself (append
& co) but you can change what the slice refers to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With