golang中的那些坑之迭代器中的指针使用

Posted elnino

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang中的那些坑之迭代器中的指针使用相关的知识,希望对你有一定的参考价值。

今天在编写代码的时候,遇到了一个莫名其妙的错误,debug了半天,发现这是一个非常典型且易犯的错误.记之

示例代码:

package main
import "fmt"
type aa struct {
        x, y int 
}
type bb struct {
        member aa
}
func main() {
        m := []*aa{}
        pool := []bb {
                {
                        member: aa{x : 1,y : 1,},
                },
                {
                        member: aa{x : 2,y : 2,},
                },
                {
                        member: aa{x : 3,y : 3,},
                },
        }
        for _, p := range pool {
                m = append(m, &p.member)
        }
        for _, ele := range m { 
                ele.x = ele.x + 1 
                ele.y = ele.y + 1 
        }

        for _, ele := range m { 
                fmt.Printf("x=%d, y=%d
", ele.x, ele.y)
        }
}

上面这段代码的运行结果是什么?也许你会立马答出来是:

x=2, y=2

x=3, y=3

x=4, y=4

运行一下就知道这个答案是错的.正确的运行结果是:

x=6, y=6

x=6, y=6

x=6, y=6

 

那么到底错在哪呢?原来在数组m中,它的三个元素是同一个指针.原来在下面这段代码中,golang是新建了一个变量p, 每次将该数组的元素

赋值给这个p,而p的地址自然是恒定的,因此最后m中的元素都是这个p的成员变量member的地址.

       for _, p := range pool {
                m = append(m, &p.member)
        }

 

这个例子告诉我们,在golang的数组/map迭代操作中,如果在迭代体中需要访问数组/map元素的指针,那么千万要小心了.这类bug非常难以检测.

以上是关于golang中的那些坑之迭代器中的指针使用的主要内容,如果未能解决你的问题,请参考以下文章

FreeSwitch那些坑之CallCenter

从片段着色器中的地形高程数据计算法线

Golang中的Reader如何自动迭代循环?

片段着色器中的OpenGL点精灵旋转

片段着色器中的球面映射

有没有办法在片段着色器中使用先前渲染的结果?