加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Golang:slice之append时原数组发生变化的问题

发布时间:2020-12-16 18:41:03 所属栏目:大数据 来源:网络整理
导读:使用append可以在slice之后追求元素,例如 nums: =[]int{ 1 , 2 , 3 } result: =append(nums, 4 )fmt .Println (result) 这段代码很简单,输出result的值为:[1 2 3 4] 问题在于,进行这种操作时,原来的slice(即nums)所基于的数组的值会不会发生变化呢?

使用append可以在slice之后追求元素,例如

nums:=[]int{1,2,3}
result:=append(nums,4)
fmt.Println(result)

这段代码很简单,输出result的值为:[1 2 3 4]
问题在于,进行这种操作时,原来的slice(即nums)所基于的数组的值会不会发生变化呢?在Golang中,如果有多个slice基于了同一个数组,则这些slice的数据是共享的(而不是每个slice复制一份)。也就说,如果改变了数组的内容,则基于它的所有slice的值都会变化这段代码中nums的值没有变化,但是并非所有时候都是如此。

回答这个问题,首先需要了解append函数实现原理:
1. 如果nums的cap够用,则会直接在nums指向的数组后面追加元素,返回的slice和原来的slice是同一个对象。显然,这种情况下原来的slice的值会发生变化!
2. 如果nums的cap不够用(上述代码就是这种情况),则会重新分配一个数组空间用来存储数据,并且返回指向新数组的slice。这时候原来的slice指向的数组并没有发生任何变化!
3. 当然,在任何情况下,返回的结果都是追加之后的slice,这一点没有问题!

以下代码用来验证这个问题:
(1)在函数test1nums的值发生变化了,因为nums[:2]的len为2,cap为3,所以追加一个元素时cap依然够用;
(2)在函数test2nums的值没有发生变化,因为nums[:2]的cap不够用,因此会重新分配一个数组用来存储新的数据,而nums存储的仍然是老数组。

func test1() {
    nums := []int{1,3}
    _ = append(nums[:2],4)
    fmt.Println("test1:",nums)

    //nums changes because the cap is big enought,the original array is modified.

}

func test2() {
    nums := []int{1,3}
    c := append(nums[:2],[]int{4,5,6}...)
    fmt.Println("test2:",nums)
    fmt.Println("cc:",c)

    //nums dont't change because the cap isn't big enought.
    //a new array is allocated while the nums still points to the old array.
    //Of course,the return value of append points to the new array.
}

<完结>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读