一、range易错用法
1.错误用法
如下代码与预期不符,预期应该是map的value依次是1,2,3,4
package main
import "fmt"
func main() {
slice := []int{0, 1, 2, 3}
myMap := make(map[int]*int)
for index, value := range slice {
myMap[index] = &value
}
fmt.Println("=====new map=====")
prtMap(myMap)
}
func prtMap(myMap map[int]*int) {
for key, value := range myMap {
fmt.Printf("map[%v]=%v\n", key, *value)
}
}
2.正确用法
如下代码运行符合预期结果
package main
import "fmt"
func main() {
slice := []int{0, 1, 2, 3}
myMap := make(map[int]*int)
for index, value := range slice {
fmt.Println("value:", &value, value)
num := value
fmt.Println("num:", &num, num)
myMap[index] = &num
}
fmt.Println("=====new map=====")
prtMap(myMap)
}
func prtMap(myMap map[int]*int) {
for key, value := range myMap {
fmt.Printf("map[%v]=%v\n", key, *value)
}
}
二、range原理
观察代码结果,发现value的地址都一样,num的地址不一样,value每次赋值会被改变,range的真实设计模式可以类比如下代码逻辑,value 实际是一个for循环外部的一个内存地址,每次循环的值会写入value所在内存中,但是如果直接使用这块地址,就会导致所有的map元素指向同一块地址,最后所有的map元素的值都是最后一次循环给value中写入的值
var value int
for index, v := range slice {
value = v
myMap[index] = &value
}