为什么我的2D golang数组会用相同值的一行一行填充?

时间:2018-02-07 01:42:13

标签: arrays go

我正在浏览Go语言,并尝试执行以下示例(填充2D数组):  https://tour.golang.org/moretypes/18 - 请参阅以下代码......

在示例中,我们应该使用值(基于我们选择的函数)填充uint8的2D数组,然后将它们显示为照片/模式。

在我的代码中,[]应该是一个填充了yy[][]uint8}行的[]uint8数组。

对于模式/数据我保持简单 - 每个yy索引(y轴),我增加放置在xx行中的值 - 所以数据应该输出一行0,然后是一行1,然后是一排2,等等。

虽然我的代码似乎可以根据下面第一个Println语句的输出正常工作(在我尝试填充2D数组yy时在循环中列出),但是存储在yy 2d数组中的最终值都是255行!它以某种方式使用最后一个x轴行的值。

我想某种方式而不是进行新的值赋值我不知何故“指向”一行被覆盖的x轴数据,所以最后我得到一个矩阵,里面填充了最后的值。行。

xx

注意:因为我正在调试,使用“fmt.Println()”会废除我手中的照片显示(但不要担心这方面)。如果删除fmt.Println()调用,则可以显示照片(尽管数据错误/意外)。

2 个答案:

答案 0 :(得分:3)

问题是yy[y] = xx无法复制xx,它会为其指定引用。

for y := range yy {
    for x := range xx {
        xx[x] = uint8((y))
    }

    // This is not a copy.
    yy[y] = xx

    fmt.Println(y, yy[y])
}

第一次迭代y = 0。它向所有xx写入0,然后yy[y] = xx 对xx的引用 分配给yy[0],而不是xx的副本1}}。

循环y = 1的下一次迭代。它会向所有xx写入1,与之前的xx相同,这也会改变xx中对yy[0]的引用。然后,它会将xx的引用分配为yy[1]。重复256次。

xxyy[0]yy[1]以及yy[2]等等都是指相同的数据。

最后打印yy时,您实际上只打印了xx 256次。您可以通过打印指针值%p来清楚地看到这一点。

fmt.Printf("%3s %p\n", "xx", xx);
for y := range yy {
    fmt.Printf("%03v %p\n", y, yy[y])
}

 xx 0xc420096000
000 0xc420096000
001 0xc420096000
002 0xc420096000
003 0xc420096000
004 0xc420096000
005 0xc420096000

解决方案是在循环中分配xx,因此每次循环迭代都会分配一个新的xx

for y := range yy {
    xx := make([]uint8, dx)

    for x := range xx {
        xx[x] = uint8((y))
    }

    // Still takes a reference to xx, but a different xx each time.
    yy[y] = xx

    fmt.Println(y, yy[y])
}

或者您可以复制xx,但这种方法更安全:不可能意外重复使用相同的参考。

答案 1 :(得分:3)

这是因为您要xxyy分配给yy := [][]uint8{ xx, xx, xx, xx, ... }中的所有地方(就像xx一样。

尝试为yy中的每个地点分配新的yy := make([][]uint8, dy) for y := range yy { xx := make([]uint8, dx)

{{1}}