golang常见问题分享——slice循环

文章讨论了在Golang中,遍历切片同时修改元素为何不会导致无限循环的问题。通过分析编译器对于`for-range`循环的实现,解释了在循环内部改变切片不会影响循环次数的原因,因为编译期间切片被复制并用于计算长度。
摘要由CSDN通过智能技术生成

golang mistakes

定期更新总结使用golang过程中遇到的常见问题。

关注我,不迷路alt

1."循环永动机"

遍历数组的同时修改数组元素,能否得到一个永远都不会停止的循环?

func main() {
    s := []int{123}
    for _, v := range s {
        s = append(s, v)
    }
    fmt.Println(s)
}

输出:

[1 2 3 1 2 3]

发现上面代码并不会一直循环下去,说明在循环内改变了切片,但不影响循环次数。

原因分析

对于 for range 语句的实现,从编译器源码 gofrontend/go/statements.cc/For_range_statement::lower_range_slice()方法中可以看到有如下注释:

 // The loop we generate:
  //   for_temp := range
  //   len_temp := len(for_temp)
  //   for index_temp = 0; index_temp < len_temp; index_temp++ {
  //           value_temp = for_temp[index_temp]
  //           index = index_temp
  //           value = value_temp
  //           original body
  //   }

go代码表示如下:

sa := s
sv1 := 0
sn := len(sa)
v1 := sv1
v2 := nil
for ; sv1 < sn; sv1++ {
  tmp := sa[sv1]
  v1, v2 = sv1, tmp
}

go语言在编译期间将切片赋值给一个新变量sa,在赋值过程中发生了复制,又通过len获取了切片的长度,这就解释了在for range循环里面增加切片的元素,不会影响循环次数的原因。 alt

本文由 mdnice 多平台发布

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值