golang内幕之for-range-value

func ForRangeValue_1() {
	var mapAges map[string]int
	mapAges = make(map[string]int)
	mapAges["name-1"] = 1
	mapAges["name-2"] = 2
	mapAges["name-3"] = 3

	var newAges map[string]*int
	newAges = make(map[string]*int)

	for k, v := range mapAges {
		newAges[k] = &v;
	}

	for k, v := range newAges {
		fmt.Println(k, v, *v)
	}
}

咋看,很想newAges从mapAges拷贝了一份key,value的值,其实不是,运行结果如下:

=== RUN   TestForRangeValue_1
name-1 0xc0000542f0 3
name-2 0xc0000542f0 3
name-3 0xc0000542f0 3
--- PASS: TestForRangeValue_1 (0.00s)
PASS

从结果可以看出newAges的value部分,是个地址值,并且指向了同一地址。按照其他语言,for k,v应该是临时变量,每遍历一次,都会导致产生新的临时变量k,v。但golang没有,下面我们简单验证一下:

func ForRangeValue_2() {
	var mapAges map[string]int
	mapAges = make(map[string]int)
	mapAges["name-1"] = 1
	mapAges["name-2"] = 2
	mapAges["name-3"] = 3

	for k, v := range mapAges {
		fmt.Println(&k, &v, k, v)
	}
}
=== RUN   TestForRangeValue_2
0xc000048550 0xc0000542f0 name-1 1
0xc000048550 0xc0000542f0 name-2 2
0xc000048550 0xc0000542f0 name-3 3
--- PASS: TestForRangeValue_2 (0.00s)
PASS

可以看到,for k,v中每一次遍历中,k和v都指向了一个相同地址,然后每次将map的key和value按照值传递的原则,赋值给k,v。

golang这样做,有他的道理,毕竟带来一定的性能提升。

解决方案:

竟然golang编译器没给我们创建新的变量,那么我们只好自己来生成

func ForRangeValue_3() {
	var mapAges map[string]int
	mapAges = make(map[string]int)
	mapAges["name-1"] = 1
	mapAges["name-2"] = 2
	mapAges["name-3"] = 3

	var newAges map[string]*int
	newAges = make(map[string]*int)

	for k, v := range mapAges {
		var pv int = v
		newAges[k] = &pv
	}

	for k, v := range newAges {
		fmt.Println(k, v, *v)
	}
}
=== RUN   TestForRangeValue_3
name-1 0xc0000542f0 1
name-2 0xc0000542f8 2
name-3 0xc000054300 3
--- PASS: TestForRangeValue_3 (0.00s)
PASS

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值