首页 >后端开发 >Golang >为什么Reflection的`Append`函数不更新原来的Go Slice?

为什么Reflection的`Append`函数不更新原来的Go Slice?

Barbara Streisand
Barbara Streisand原创
2024-11-26 01:10:12620浏览

Why Doesn't Reflection's `Append` Function Update the Original Go Slice?

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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn