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

本文通过示例代码展示了Go语言在1.21和1.22版本中for循环变量行为的变化,包括地址值的重复和slice值的初始化。1.22版本引入的新规则以避免意外共享bug。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

示例代码

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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值