reflection - 为什么可以使用反射在 slice 中设置值?

标签 reflection go

根据 The Laws of Reflection无法按如下方式设置元素的值,您需要使用其地址。

这行不通:

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)

那么为什么在使用 slice 时以下会起作用?

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) 正在获取 value 而不是 slice floats 中的地址,因此这意味着它不应该是可设置的就像第一个例子。

最佳答案

在您的第一个示例中,您传递了实际的 x。这将复制 x 并将其提供给 reflect.ValueOf。当您尝试执行 v.SetFloat 时,因为它只得到一个副本,所以它无法更改原始的 x 变量。

在第二个示例中,您传递了 x 的地址,因此您可以通过取消引用来访问原始变量。

在第三个示例中,您将 floats 传递给 reflect.ValueOf,它是一个 slice 。 “slice 保存对底层数组的引用”(http://golang.org/doc/effective_go.html#slices)。这意味着通过 slice ,您实际上拥有对底层对象的引用。您将无法更改 slice 本身(append & co)但您可以更改 slice 所指的内容。

关于reflection - 为什么可以使用反射在 slice 中设置值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24440902/

相关文章:

java - int.class 返回什么

Java 反射 Bean 属性 API

c# - 检查两个对象的属性以进行更改

go - NAT 后面的两个节点之间如何通信?

json - Go:指向接口(interface){} 的指针丢失底层类型

pointers - 反射(reflect) : setting a field of a pointer

mysql - Golang Gorm 错误迁移结构

使用 eq 和 index 的 Go 模板

go - 在 Go 中解析表单数组

go - GO 中的包/函数中毒