我想仅使用反射附加到切片。但我无法弄清楚如何替换" a
与新切片的值。
func main() {
fmt.Println("Hello, playground")
a := []string {"a","b","c"}
values := []string {"d","e"}
v := reflect.ValueOf(a)
fmt.Printf("%t\n\n", v.Type())
fmt.Printf("%t\n\n", v.Type().Elem().Kind())
for _, val := range values {
v.Set(reflect.Append(v, reflect.ValueOf(val)))
}
fmt.Printf("%t - %v", a, a)
}
此代码可用于摆弄https://play.golang.org/p/cDlyH3jBDS。
答案 0 :(得分:1)
如果它来自非指针,则无法修改reflect.Value
中包含的值。如果允许,您只能修改副本并导致更多混淆。切片值是包含指向后备阵列的指针,长度和容量的标头。当您将a
传递给reflect.ValueOf()
时,会生成并传递此标头的副本,您可以对其执行的任何修改都只能修改此标头副本。原始切片头不会观察到添加元素(从而改变其长度以及潜在的指针和容量),原始切片头仍将指向相同的数组,并且仍将包含相同的长度和容量值。有关详细信息,请参阅Are Golang function parameter passed as copy-on-write?;和Golang passing arrays to the function and modifying it。
您必须从指针开始,并且可以使用Value.Elem()
来获取指向的,解除引用的值的reflect.Value
描述符。但你必须从指针开始。
在代码中更改此单行可使其正常工作:
v := reflect.ValueOf(&a).Elem()
并且要打印值的类型,请使用%T
动词(%t
用于bool
值):
fmt.Printf("%T\n\n", v.Type())
fmt.Printf("%T\n\n", v.Type().Elem().Kind())
// ...
fmt.Printf("%T - %v", a, a)
输出(在Go Playground上尝试):
Hello, playground
*reflect.rtype
reflect.Kind
[]string - [a b c d e]
要更深入地了解Go的反思,请阅读博文:The Laws of Reflection
阅读相关问题+答案:
Assigning a value to struct member through reflection in Go
Changing pointer type and value under interface with reflection