为了账号安全,请及时绑定邮箱和手机立即绑定

Go subslice 指针引用

Go subslice 指针引用

Go
慕雪6442864 2022-05-05 15:58:27
结果s是[1, 2, 3],我认为切片包含对底层数组的引用。不是这样吗?package mainimport (    "fmt")func main() {    s := []int{1, 2, 3}    ss := s[1:]    ss = append(ss, 4)    for _, v := range ss {        v += 10    }    for i := range ss {        ss[i] += 10    }    fmt.Println(s)}
查看完整描述

2 回答

?
月关宝盒

TA贡献1772条经验 获得超5个赞

我认为切片包含对底层数组的引用。不是这样吗?


是的。但是您使用以下语句创建了一个长度为 3 的数组:


s := []int{1, 2, 3}

当您将元素附加到ss时,需要分配一个新的更长的数组。因此,您失去了与此声明之间的ss联系s:


ss = append(ss, 4)

您可以通过运行以下示例来验证这一点:


package main


import (

    "fmt"

)


func main() {

    s := []int{1, 2, 3}

    ss := s[1:]

    ss[0] += 5

    ss = append(ss, 4)

    ss[0] += 100

    fmt.Println(s)

}

哪个打印[1 7 3]。


如果您将初始化的s长度更改为大于三,则不需要新的数组分配,s并且ss将保持 和 之间的链接:


package main


import (

    "fmt"

)


func main() {

    s := make([]int, 3, 4)

    s[0], s[1], s[2] = 1, 2, 3

    ss := s[1:]

    ss[0] += 5

    ss = append(ss, 4)

    ss[0] += 100

    fmt.Println(s)

}

输出:[1 107 3]


理论上认为问题是切片的范围副本的答案是不正确的,可以通过以下示例显示:


package main    


import (    

    "fmt"    

)    


func main() {    

    s := make([]int, 3, 4)    

    s[0], s[1], s[2] = 1, 2, 3    

    ss := s[1:]    

    ss = append(ss, 4)    

    for i := range ss {    

        ss[i] += 10    

    }    

    fmt.Println(s)    

}    

输出:[1 12 13]


查看完整回答
反对 回复 2022-05-05
?
杨魅力

TA贡献1811条经验 获得超6个赞

似乎您已经创建了 slice 的副本s,并且您已经对 slice 副本进行了更改,ss认为这些更改也会传递给制作副本的 slice。

第一个 for 循环也遍历 slice 的元素ss,但实际上并没有对它们做任何事情,因为range在为您提供元素值时也会创建一个副本,所以它实际上并没有做任何事情!

您似乎正在尝试执行以下操作:

  1. 将值附加4到切片s

  2. 从索引 1slice到切片末尾的每个值,并添加10

如果是这种情况,这应该可以帮助您实现:

package main


import (

    "fmt"

)


func main() {

    s := []int{1, 2, 3}

    s = append(s, 4)


    for i := range s {

        if i == 0 {

            continue

        }

        s[i] += 10

    }


    fmt.Println(s)

}


查看完整回答
反对 回复 2022-05-05
  • 2 回答
  • 0 关注
  • 177 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号