1. 程式人生 > >Golang 語言坑之for-range

Golang 語言坑之for-range

ola light import amp make 結構 pen 指針 code

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)
	}
}

  

Golang 語言坑之for-range