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

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

Barbara Streisand
发布: 2024-11-26 01:10:12
原创
623 人浏览过

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

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板