我正在浏览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()调用,则可以显示照片(尽管数据错误/意外)。
答案 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次。
xx
,yy[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)
这是因为您要xx
将yy
分配给yy := [][]uint8{ xx, xx, xx, xx, ... }
中的所有地方(就像xx
一样。
尝试为yy
中的每个地点分配新的yy := make([][]uint8, dy)
for y := range yy {
xx := make([]uint8, dx)
:
{{1}}