根据反射定律,不可能按如下方式设置元素的值,您需要使用其地址.
这不起作用:
var x float64 = 3.4
v := reflect.ValueOf(x)
v.SetFloat(7.1) // Error: will panic.
Run Code Online (Sandbox Code Playgroud)
这将有效:
var x float64 = 3.4
p := reflect.ValueOf(&x) // Note: take the address of x.
p.Elem().SetFloat(7.1)
Run Code Online (Sandbox Code Playgroud)
那么为什么使用切片时以下工作呢?
floats := []float64{3}
v := reflect.ValueOf(floats)
e := v.Index(0)
e.SetFloat(6)
fmt.Println(floats) // prints [6]
Run Code Online (Sandbox Code Playgroud)
http://play.golang.org/p/BWLuq-3m85
当然v.Index(0)是从片中取值而不是地址floats,因此意味着它不应像第一个例子那样设置.
在您的第一个示例中,您传递了实际值x.这将复制x并提供给它reflect.ValueOf.当您尝试这样做时v.SetFloat,因为它只获得一个副本,它无法更改原始x变量.
在第二个示例中,您传递了地址x,因此您可以通过解除引用来访问原始变量.
在第三个示例中,您将传递floats给reflect.ValueOf切片."Slice保存对底层数组的引用"(http://golang.org/doc/effective_go.html#slices).这意味着通过切片,您实际上有一个对底层对象的引用.您将无法更改切片本身(append&co),但您可以更改切片所指的内容.