GO切片问题:一个切片从中间删除用另外一个变量接收原切片值变化的原理是啥?

作者站长头像
站长
· 阅读数 9

一个go切片的问题

    var i = 3
    nums := []int{1, 2, 3, 4, 5, 6}
    nums6 := append(nums[:i], nums[i+2:]...)
    fmt.Println(nums, nums6)

这段代码nums 最终输出为什么变成了[1,2,3,6,5,6]输出内容为:// [1 2 3 6 5 6] [1 2 3 6]看这个输入nums应该是改动了,但是为什么5,6又还在呢

回复
1个回答
avatar
test
2024-06-20

看官方对 append 描述,Appending_and_copying_slices

首先 append 用法:

append(s S, x ...E) S // core type of S is []E

里面这么说的:

If the capacity of s is not large enough to fit the additional values, append allocates a new, sufficiently large underlying array that fits both the existing slice elements and the additional values. Otherwise, append re-uses the underlying array.

如果 append 之后的数据并没有超过 s 原本的容量,那么就会利用原本的 底层数组,也就是你等于是在原切片的底层数据上对应位置进行了改动。

然后对于切片的解释: slices-introgolang中切片由三部分组成:answer image

所以结合 append 不超过原本切片对象的容量时候,在原本指针所指向的 underlying array 做了修改,并返回;如果超过原本切片的容量,那就会重新 reallocate 一个新的 underlying array予以返回。

将你的例子进行扩展,不改变容量的时候:

nums8 := append(nums[:4], 100)
fmt.Println("------", nums8, nums)
// ------ [1 2 3 4 100] [1 2 3 4 100 6]

就是这个道理。。。

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容