golang面试基础系列-range的坑(三)
在 Go
中,for range
用来遍历 slice, map, chan
等,使用频率很高,但遍历虽好用,却很容易踩坑,且看 demo
如下:
1. 只有一个返回值时,则第一个参数是 index
package main import "fmt" func main() { s := []string{"a", "b", "c"} // 只有一个返回值:则第一个参数是index for v := range s { fmt.Println(v) } // 两个返回值 for i, v := range s { fmt.Println(i, v) } }
输出结果如下:
0 1 2 ============= 0 a 1 b 2 c
2. 遍历 map
为随机序输出,slice
为索引序输出
package main import "fmt" func main() { m := make(map[string]string) m["aaa"] = "AAA" m["bbb"] = "BBB" m["ccc"] = "CCC" m["ddd"] = "DDD" m["eee"] = "EEE" // range map 为随机序输出 for i, v := range m { fmt.Println(i, v) } fmt.Println("==================") s := []string{"aaa", "bbb", "ccc", "ddd", "eee"} // range slice 为索引序输出 for i, v := range s { fmt.Println(i, v) } }
输出结果如下:
ddd DDD eee EEE aaa AAA bbb BBB ccc CCC ================== 0 aaa 1 bbb 2 ccc 3 ddd 4 eee
3. range v 是值拷贝,且只会声明初始化一次
package main import "fmt" func main() { ParseStudent() } type student struct { Name string Age int } func ParseStudent() { m := make(map[string]*student) stus := []student{ {Name: "zhang", Age: 22}, {Name: "li", Age: 23}, {Name: "wang", Age: 24}, } for _, stu := range stus { // 都指向了同一个stu的内存指针,为什么? // 因为 for range 中的 v 只会声明初始化一次 // 不会每次循环都初始化,最后赋值会覆盖前面的 fmt.Printf("%p\n", &stu) // 1. bad m[stu.Name] = &stu // 2. good /*newStu := stu m[stu.Name] = &newStu*/ } for i, v := range m { fmt.Println(i, v) } }
输出结果如下:
0xc00008e020 0xc00008e020 0xc00008e020 zhang &{wang 24} li &{wang 24} wang &{wang 24}
正确做法应该是:将 good
部分注释打开,运行结果如下:
0xc00000c080 0xc00000c080 0xc00000c080 li &{li 23} wang &{wang 24} zhang &{zhang 22}
<br/>
小结:for range
遍历注意以上几个小坑:
- 只有一个返回值时,则第一个参数是
index
; - 遍历
map
为随机序输出,slice
为索引序输出; range v
是值拷贝,且只会声明初始化一次;
掌握以上几点后,就让我们愉快的使用 range
吧~
相关推荐
Lzs 2020-10-23
Justhavefun 2020-10-22
周游列国之仕子 2020-09-15
风雨断肠人 2020-09-04
聚合室 2020-11-16
零 2020-09-18
jacktangj 2020-10-14
ChaITSimpleLove 2020-10-06
Andrea0 2020-09-18
afanti 2020-09-16
88234852 2020-09-15
YClimb 2020-09-15
卖口粥湛蓝的天空 2020-09-15
stulen 2020-09-15
pythonxuexi 2020-09-06
abfdada 2020-08-26
梦的天空 2020-08-25