loopvar 改动不同版本的影响-基础循环

示例代码

package main

import (
	"fmt"
	"runtime"
)

func main() {
	fmt.Println("golang version:", runtime.Version())
	for i := 0; i < 10; i++ {
		fmt.Println(&i)
	}
}

代码说明

这个代码先打印了使用的golang的版本,然后进行一个for循环,for循环中打印了变量i的地址
执行go run xxx.go看下结果

golang 1.21的运行结果

go run demo/basic_for.go
golang version: go1.21.5
0xc0000120d8
0xc0000120d8
0xc0000120d8
0xc0000120d8
0xc0000120d8
0xc0000120d8
0xc0000120d8
0xc0000120d8
0xc0000120d8
0xc0000120d8

可以看到在1.21.5这个版本中,打印出来的地址都是一样的,在1.22中又会如何呢

golang 1.22的运行结果

go run demo/basic_for.go
golang version: go1.22.1
0xc0000a6020
0xc0000a6028
0xc0000a6030
0xc0000a6038
0xc0000a6040
0xc0000a6048
0xc0000a6050
0xc0000a6058
0xc0000a6060
0xc0000a6068

可以看到在1.22.1的这个版本中,打印出来的地址都是不一样的。

再举个例子

package main

import (
	"fmt"
)

func main() {
	var ids []*int
	for i := 0; i < 10; i++ {
		ids = append(ids, &i)
	}
	for _, v := range ids {
		fmt.Println("demo i value:", *v)
	}
}

在1.21的版本中的结果:

golang version: go1.21.5
demo i value:10,demo i value:10,demo i value:10,demo i value:10,demo i value:10,demo i value:10,demo i value:10,demo i value:10,demo i value:10,demo i value:10,

可以看到ids这个slice中的值都是10

在1.22的版本中的结果

`golang version: go1.22.1
demo i value:0,demo i value:1,demo i value:2,demo i value:3,demo i value:4,demo i value:5,demo i value:6,demo i value:7,demo i value:8,demo i value:9,

上述的1.21存在问题的代码有比较简单的解决办法就是在循环中加上一行代码i:=i就可以解决问题。
出现上述问题的原因是1.22 loopvar的规则变了,1.22之前的版本中for循环中的变量只会循环一次,不论需要循环多少次都只初始化一次,但是1.22中变成了每次循环都会创建新变量,以避免意外共享bug。
golang的release note是这么描述的Previously, the variables declared by a “for” loop were created once and updated by each iteration. In Go 1.22, each iteration of the loop creates new variables, to avoid accidental sharing bugs.

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值