Go循环指针更改

时间:2015-09-04 15:44:10

标签: pointers go reference slice

我在Go中使用ref循环迭代一段结构。

在每个循环中,我指向变量的当前项。

我很困惑为什么指针在下一个循环中改变了值。

例如this code

for range

我希望能够产生:

package main

import "fmt"

type t struct {
    val int
}

func main() {
    l := []t{{1}, {2}}
    var p *t
    for _, i := range l {
        fmt.Println("begin", p)
        p = &i
        fmt.Println("end", p)
    }
}

但确实如此:

begin <nil>
end &{1}
begin &{1}
end &{2}

作为参考,在我的实际代码中,我在循环期间检查条件,并返回当前项和前一项。所以我试图保存一个指针,以便在下一次迭代中它也可以访问前一个。

3 个答案:

答案 0 :(得分:1)

建立Tim's comment,看起来你可以复制每个循环上的值,而不是指针,然后取消引用它。

package main

import "fmt"

type t struct {
    val int
}

func main() {
    l := []t{{1}, {2}}
    var p t
    var i t
    for _, i = range l {
        fmt.Println("begin", &p)
        p = i
        fmt.Println("end", &p)
    }
}

答案 1 :(得分:1)

另一种选择是使用索引获取指向当前项目的指针:

package main

import "fmt"

type t struct {
    val int
}

func main() {
    l := []t{{1}, {2}}
    var p *t

    for index, _ := range l {
        fmt.Println("begin", p)
        p = &l[index]
        fmt.Println("end", p)
    }
}

答案 2 :(得分:1)

问题是你要获取循环/范围变量的地址而不是切片中项目的地址。但是,你只是为自己做了很多不必要的工作。首先,为什么不使用i, v := range或更好i, _ :=然后你可以i-1来获取上一个项目?其次,即使您希望将其保存在指针中,仍然使用此语法然后分配p = &l[i],这样您就可以获得切片中项目的地址,而不是循环/范围变量的地址。

当使用索引显然更好时,人们太急于使用/每个样式构造...如果你想在每次迭代中使用index-1,那么使用索引应该是你的方法。