为什么可以使用反射在切片中设置一个值



根据反射法则,元素的值不可能像下面这样设置,你需要使用它的地址。

这行不通:

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的引用。

相关内容

  • 没有找到相关文章