map
1、for range map 在开始执行循环的时候,底层做了随机种子,故其循环是随机的。
package main import "fmt" func main() { a := map[int]int{0: 1, 1: 2, 2: 3, 3: 4, 4: 5} for _, c := range a { fmt.Println(c) } }
输出: 3 4 5 1 2 多次执行,结果不同
数组
package main import "fmt" func main() { a := [5]int{0: 1, 1: 2, 2: 3, 3: 4, 4: 5} for b, c := range a { if b == 0 { a[1] = 22 //fmt.Println(b) } a[b] = c + 10 } fmt.Println(a) }
输出: [11 12 13 14 15]
//a[1] = 22 并没有起作用,因数组是值类型,使用range获取的数组项是复制过来的,并非引用原始数据。
如果想a[1] = 22 有效,只需改成引用。
package main import "fmt" func main() { a := [5]int{0: 1, 1: 2, 2: 3, 3: 4, 4: 5} for b, c := range &a {//注意此处改变 if b == 0 { a[1] = 22 //fmt.Println(b) } a[b] = c + 10 } fmt.Println(a) }
结果: [11 32 13 14 15]
slice
slice 是引用类型,底层指针指向数组,传参的时候传引用和传值区别不大。
示例1
package main import "fmt" func main() { a := []int{0: 1, 1: 2, 2: 3, 3: 4, 4: 5} for b, c := range a { if b == 0 { a[1] = 22 //fmt.Println(b) } a[b] = c + 10 } fmt.Println(a) }
结果: [11 32 13 14 15] 对比上一个例子,不需要传引用就可以更改a[1] = 22
示例2
这个是输出异常的示例
package main import ( "fmt" ) func main() { a := []int{1, 2, 3} b := make([]*int, len(a)) for i, v := range a { //解决办法1增加临时变量 //vv := v //b[i] = &vv //解决办法2 //b[i] = &a[i] b[i] = &v } for _, v := range b { fmt.Println(*v) } }
输出: 3 3 3
原因v变量在for range中只会创建一次,之后迭代重复使用
迭代闭包容易出问题
package main import ( "fmt" "time" ) func main() { a := []int{0: 1, 1: 2, 2: 3, 3: 4, 4: 5} for _, c := range a { go func() { fmt.Println(c) }() } time.Sleep(3 * time.Second) }
结果为: 3 3 5 5 5 有两种方法解决以上问题
1、增加一个临时变量
package main import ( "fmt" "time" ) func main() { a := []int{0: 1, 1: 2, 2: 3, 3: 4, 4: 5} for _, c := range a { cc:=c //增减临时变量cc go func() { fmt.Println(cc) }() } time.Sleep(3 * time.Second) }
2、 传参进去
package main import ( "fmt" "time" ) func main() { a := []int{0: 1, 1: 2, 2: 3, 3: 4, 4: 5} for _, c := range a { go func(c int) { fmt.Println(c) }(c) } time.Sleep(3 * time.Second) }
循环子协程
package main import ( "fmt" "time" ) type v struct { value int } func (vv *v) show() { fmt.Println(vv.value) } func main() { a := []v{{1}, {2}, {3}} for _, c := range a { go c.show() } time.Sleep(3 * time.Second) }
输出: 3 3 3 解决办法 1、增加临时变量
package main import ( "fmt" "time" ) type v struct { value int } func (vv *v) show() { fmt.Println(vv.value) } func main() { a := []v{{1}, {2}, {3}} for _, c := range a { c := c //增加这一行 go c.show() } time.Sleep(3 * time.Second) }
2、使用指针
package main import ( "fmt" "time" ) type v struct { value int } func (vv *v) show() { fmt.Println(vv.value) } func main() { a := []*v{{1}, {2}, {3}} for _, c := range a { go c.show() } time.Sleep(3 * time.Second) }
3、方法show接受者不用指针
package main import ( "fmt" "time" ) type v struct { value int } func (vv v) show() { fmt.Println(vv.value) } func main() { a := []v{{1}, {2}, {3}} for _, c := range a { go c.show() } time.Sleep(3 * time.Second) }标签:map,常见问题,fmt,Println,range,func,time,Go,main From: https://www.cnblogs.com/minch/p/17484967.html