1.23 版本, for-range 指针数组,闭包捕获的 range 变量为什么还是最后一个呢?

19 小时 7 分钟前
 dyllen
for _, cg := range consumers {
		log.Logger.Infof("%p", cg)
		utils.SafeGo(func() {
			log.Logger.Infof("%#v", cg)
			log.Logger.Infof("%p", cg)
			StartConsumer(ctx, cfg.Endpoint, cfg.AccessKey, cfg.SecretKey, cg)
		})
	}

输出:

0xc000683540
0xc000683560
&queue.Test2{groupName:"test2"}
&queue.Test2{groupName:"test2"}
0xc000683560
0xc000683560

consumers 包含两个元素,值都是指针。 1.22 版本开始 range 每次不是会创建新变量了吗?为什么我 SafeGo 里面 cg 拿到的还是最后一个的值?

627 次点击
所在节点    Go 编程语言
6 条回复
fireice
18 小时 48 分钟前
用匿名函数的参数传进去就 ok 了
dyllen
18 小时 14 分钟前
@fireice 按道理 1.22 开始版本不需要这样做了呀,我的疑惑就是这里。
zealot0630
17 小时 26 分钟前
cg 变量从头到尾都只有一个啊,所有匿名函数捕获的变量都指向这同一个 cg
pike0002
15 小时 36 分钟前
检查下 go.mod 里面的 go 的版本,如果是 1.22 之前的话新的特性就不会生效
dyllen
13 小时 27 分钟前
@zealot0630 每次循环 cg 变量都是不同的,你看输出的指针地址。
https://go.dev/play/p/kV2gxXfzVfc 你看看整个测试代码,我帖子里面的代码和这个测试的一样的,就除了 slice 的数据类型不同。
dyllen
13 小时 18 分钟前
@pike0002 还真是,我一直以为 go.mod 里面那个版本只是用来看我这个项目需要的最低 go 版本,原来还会影响实际运行版本的行为。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1090916

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX