【问题标题】:Why does Go slice `append()` not take a reference?为什么 Go slice `append()` 不带引用?
【发布时间】:2014-01-10 02:40:47
【问题描述】:

Go Lang 的切片 append() 可能会分配一个新的后备数组来为新项目腾出空间。因此,在调用z = append(x,y) 之后,如果z 的最前面的元素被修改,x 本质上是未指定的——它可能具有或不具有与z 相同的后备数组,并且z 可能会发生变异它的后备数组带有z[0] = foo,因此可能会也可能不会修改x 的后备数组。

那么,为什么要让这种丑陋浮出水面呢?而是将 append 的结果分配给除第一个参数之外的任何内容,而是将其作为程序错误,为什么不让 append 取而代之的是 *[]T,这样就不需要重新分配,也没有未定义的变量悬空。

这不会解决所有情况,因为a = x; append(&x,y) 仍会使a 未定义,但部分改进似乎总比没有好。

【问题讨论】:

    标签: go


    【解决方案1】:

    在您的第一个示例 (z = append(x, y)) 中,x 未定义并不完全正确。相反,x 仍然指向 x 的原始内容,而 z 指向这些内容,然后是一些内容。正如您所提到的,有两种可能性:

    • cap(x) > len(x),在这种情况下,append 只返回 x[:len(x)+1](即,扩展返回切片的长度以包含一个额外的元素)
    • cap(x) == len(x),在这种情况下,append 通过复制 x 的内容创建另一个数组,然后将 y 附加为 len(x)-th 元素。

    在这两种情况下,x 基本上保持不变,因为x 的所有元素仍然存在。您现在显然必须小心,因为您可能有两个对相同基础数据的引用,但重点是保留 x 可能很有用。

    也就是说,我同意让append 获取指针可能会更简单,而且我刚刚描述的这种可能的用例可能不够普遍,不足以保证可能令人困惑、稍微冗长的语义。

    【讨论】:

    • 修改了我的介绍以澄清修改z 使x 具有未指定的内容。
    猜你喜欢
    • 2021-11-24
    • 2021-09-03
    • 2015-07-24
    • 2021-10-02
    • 1970-01-01
    • 2011-01-07
    • 2014-01-25
    • 2021-08-28
    • 2023-01-01
    相关资源
    最近更新 更多