根据反射法则,元素的值不可能像下面这样设置,你需要使用它的地址。
这行不通:
var x float64 = 3.4
v := reflect.ValueOf(x)
v.SetFloat(7.1) // Error: will panic.
var x float64 = 3.4
p := reflect.ValueOf(&x) // Note: take the address of x.
p.Elem().SetFloat(7.1)
那么为什么下面的代码在使用切片时可以正常工作呢?
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 显然v.Index(0)
取值而不是从片floats
取地址,因此它不应该像第一个例子那样可设置。
在您的第一个示例中,您通过了实际的x
。这将复制x
并将其交给reflect.ValueOf
。当您尝试执行v.SetFloat
时,由于它只获得一个副本,因此无法更改原始x
变量。
在第二个示例中,传递了x
的地址,因此可以通过解引用来访问原始变量。
在第三个示例中,将floats
传递给reflect.ValueOf
,这是一个片。切片保存对底层数组的引用(http://golang.org/doc/effective_go.html#slices)。这意味着通过切片,你实际上有一个对底层对象的引用。你将无法改变切片本身(append
&),但是可以更改slice的引用。