再练for-range

题目:

下面这段代码输出的是什么?请说明原因。

1
2
3
4
5
6
7
8
9
10
11
12
func main() {
slice := []int{0,1,2,3}
m := make(map[int]*int)

for key,val := range slice {
m[key] = &val
}

for k,v := range m {
fmt.Println(k,"->",*v)
}
}

答案

1
2
3
4
0 -> 3
1 -> 3
2 -> 3
3 -> 3

解析:

​ for range 循环的时候会创建每个元素的副本,而不是元素的引用。

​ 在使用for-range循环里,每次遍历使用的val都是对同一个元素的遍历赋值,故在第一个for循环里,每次使用的都是val的元素进行赋值,即map中所有的元素的值都是变量val的地址。

​ 在最后一次遍历时,val指向slice的最后一个元素的地址,即3的地址。故最后的输出都是3。

正确的写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
func main() {
slice := []int{0, 1, 2, 3}
m := make(map[int]*int)

for key, val := range slice {
v := val
m[key] = &v
}

for k, v := range m {
fmt.Println(k, "->", *v)
}
}

再练for-range
http://example.com/2023/04/30/Go每日一题/再练for-range/
作者
Feng Tao
发布于
2023年4月30日
更新于
2023年4月30日
许可协议