go只提供了一种循环方式,即for循环,其中有两种方式。第一种是for [initStmt];[Condition];[PostStmt]{}

for i:=0;i++;i<10{

}
 第二种是for-range可以用来历容器类型如数组、切片和映射,channel 。但是使用for-range时,如果使用不当会程序运行不是预期结果,例如,下面的示例程序将遍历一个切片,并将切片的值当成切片值存入,切片类型是一个结构体,切片的类型是为Point型,值是一个地址。

package main

import “log”

/**

Created by GoLand
GO Version : go1.10.3
Project: Boring
Created by Kaifoon
Created with 2018/10/8 21:57

**/

type Point struct {
x int
y int

}

func main() {
r := make([]*Point,4)
d := []Point{
{1,3},
{3,3},
{3,48},
{8,2},
}
for _,v := range d {
r = append(r,&v)
}
for _,v := range r {
log.Println(*v)
}
}
  我们希望结果是

2018/10/08 22:44:50 {1 3}
2018/10/08 22:44:50 {3 3}
2018/10/08 22:44:50 {3 48}
2018/10/08 22:44:50 {8 2}

Process finished with exit code 0
  但是实际运行是这样的

2018/10/08 22:44:50 {8 2}
2018/10/08 22:44:50 {8 2}
2018/10/08 22:44:50 {8 2}
2018/10/08 22:44:50 {8 2}

Process finished with exit code 0
  由输出可以知道,程序取最后迭代的值写入。经过debug发现,原来for-range 时 v 是复制切片的的值,然而v的指针地址是没变的。所以迭代完成的时候,因为读取的v的指针,v的地址被写入,装入的值也是最后迭代的值。正确程序如下:
package main

import “log”

/**

Created by GoLand
GO Version : go1.10.3
Project: Boring
Created by Kaifoon
Created with 2018/10/8 21:57

**/

type Point struct {
x int
y int

}

func main() {
r := make([]*Point,0)
d := []Point{
{1,3},
{3,3},
{3,48},
{8,2},
}
for _,v := range d {
vv := v
r = append(r,&vv)
}
for _,v := range r {
log.Println(*v)
}
}
在这里插入图片描述