Go 反射中的附加函数
在 Go 中,使用反射将元素附加到切片似乎不会更新原始切片。下面的代码说明了这一点:
func appendToSlice(arrPtr interface{}) { valuePtr := reflect.ValueOf(arrPtr) value := valuePtr.Elem() value = reflect.Append(value, reflect.ValueOf(55)) fmt.Println(value.Len()) // prints 1 } func main() { arr := []int{} appendToSlice(&arr) fmt.Println(len(arr)) // prints 0 }
为什么不起作用?
根本原因在于reflect.Append的行为。与传统的追加函数一样,它返回一个新的切片值。在这种情况下,分配给 value 变量的值将替换为这个新切片,从而有效地创建副本。
为了说明这一点,让我们修改示例以突出显示发生的情况:
func appendToSlice(arrPtr *[]int) { value := *arrPtr value = append(value, 55) fmt.Println(len(value)) } func main() { arr := []int{} appendToSlice(&arr) fmt.Println(len(arr)) }
即使我们没有使用,修改后的代码也会产生相同的输出
解决方案
要使用反射正确追加到切片,我们需要使用 Value.Set 方法修改原始值:
func appendToSlice(arrPtr interface{}) { valuePtr := reflect.ValueOf(arrPtr) value := valuePtr.Elem() value.Set(reflect.Append(value, reflect.ValueOf(55))) fmt.Println(value.Len()) }
此方法将新创建的切片传递给 value.Set,更新原始切片。
以上是为什么Reflection的`Append`函数不更新原来的Go Slice?的详细内容。更多信息请关注PHP中文网其他相关文章!