每次学习并整理一个Golang的知识点,每天进步一点点。今天来学习下range的一个知识点🤔。
代码片段
看如下这段代码,并猜测输出结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
package main
import "fmt"
func newMap() map[int]*string {
s := []string{"a", "b", "c", "d"}
m := make(map[int]*string)
for key, value := range s {
m[key] = &value
}
return m
}
func newMap2() map[int]*string {
s := []string{"a", "b", "c", "d"}
m := make(map[int]*string)
for key := range s {
m[key] = &s[key]
}
return m
}
func newMap3() map[int]string {
s := []string{"a", "b", "c", "d"}
m := make(map[int]string)
for key, value := range s {
m[key] = value
}
return m
}
func main() {
m := newMap()
m2 := newMap2()
fmt.Println("遍历m的结果:")
for k, v := range m {
fmt.Println(k, "-->", *v)
}
fmt.Println("遍历m2的结果:")
for k, v := range m2 {
fmt.Println(k, "-->", *v)
}
fmt.Println("遍历m3的结果:")
for k, v := range m3 {
fmt.Println(k, "-->", v)
}
}
|
思考后看答案
答疑解惑
代码执行结果如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
遍历m的结果:
2 --> d
3 --> d
0 --> d
1 --> d
遍历m2的结果:
0 --> a
1 --> b
2 --> c
3 --> d
遍历m3的结果:
0 --> a
1 --> b
2 --> c
3 --> d
|
需要牢记的一点,在Go的for range循环中,始终使用值复制的方式代替被遍历的元素本身,相当于for range循环的时候会创建每个元素的副本,而不是元素本身;这里range里的key和value都是临时变量,且在整个for…range循环中,临时变量会被重复利用;&value
取的就是临时变量 value 的地址,而非list中真正被遍历到的某个元素的地址,所以在map m中,m[key]
都被赋值为相同的&value
(即value的地址),而最后一次循环中 value 被赋值为d,所以输出结果都是d。
其实正确的写法可以参见newMap2
,通过s的索引来获取真实元素和他的指针地址。
而newMap3
中各元素赋值不受影响,因为纯粹是值与值的传递。
下期提问
观察如下代码片段,猜测输出结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package main
import "fmt"
func makeList() []int {
s := make([]int, 5)
s = append(s, 1, 2, 3)
return s
}
func makeList2() []int {
s := make([]int, 0)
s = append(s, 1, 2, 3)
return s
}
func main() {
s := makeList()
s2 := makeList2()
fmt.Println("打印s:", s)
fmt.Println("打印s2:", s2)
}
|
答案及解析将在下期文章中给出,欢迎大家在评论区留言,独乐乐不如众乐乐,交流学习,互相进步。
欢迎转发和评论。更多优质原创文章,欢迎关注微信公众号“IYue爱月”或扫描下方二维码:
文章作者
xujpxm
上次更新
2020-06-23
许可协议
CC BY-NC-ND 4.0 非商业转载请注明出处(作者,原文链接),商业转载请联系作者授权,谢谢!