【发布时间】:2018-02-07 10:02:57
【问题描述】:
我正在浏览 Go 语言并尝试执行以下示例(填充 2D 数组): https://tour.golang.org/moretypes/18 -- 看下面的代码...
在示例中,我们应该使用值(基于我们选择的函数)填充 uint8 的二维数组,然后将它们显示为照片/图案。
在我的代码中,yy 应该是一个 [][]uint8 数组,其中包含单行 []uint8 (xx)。
对于模式/数据,我保持简单 - 对于 yy(y 轴)的每个索引,我增加放置在 xx 行中的值 - 所以数据应该输出一行 0,然后是一行 1,然后是一排 2,等等。
尽管根据下面第一个 Println 语句的输出(在我尝试填充二维数组 yy 时在循环内列出),我的代码似乎可以正常工作,但存储在 yy 二维数组中的最终值都是 255 行!它以某种方式将最后一个 x 轴行的值用于所有内容。
我认为我不是进行新的值分配,而是以某种方式“指向”被覆盖的单行 x 轴数据,所以最后我得到一个填充了最终值的矩阵行。
package main
import (
"fmt"
"golang.org/x/tour/pic"
)
func Pic(dx, dy int) [][]uint8 {
//HERE I DYNAMICALLY CREATE THE ARRAYS BASED ON WHAT I WAS TAUGHT PREVIOUSLY
//I UNDERSTAND THAT TECHNICALLY THESE MAY BE SLICES NOT ARRAYS ...
//AND THUS MAYBE POINT SOMEWHERE AND DON'T ACTUALLY STORE ALL THE DATA (???)
yy := make([][]uint8, dy)
xx := make([]uint8, dx)
for y := range yy {
for x := range xx {
xx[x] = uint8((y)) // FOR SIMPLICITY I MADE PATTERN ROW x = y
}
yy[y] = xx
//THIS OUTPUT IS CORRECT; ROW OF 0's, ROW OF 1's, ROW OF 2's, ETC
fmt.Println(y, yy[y])
}
for y := range yy {
//THIS OUTPUT IS INCORRECT; ALL 255!
//IT POPULATED ALL ROWS W/ VALUES FROM THE LAST LOOP
fmt.Println(y, yy[y])
}
return yy
}
func main() {
pic.Show(Pic)
}
注意:因为我正在调试,使用“fmt.Println()”会取消我手中照片的显示(但不要担心这方面)。如果您删除 fmt.Println() 调用,则可以显示照片(尽管数据错误/意外)。
【问题讨论】:
-
因为切片是引用类型(指针类型)。所以
yy[y]=xx只是将具有相同底层数组的切片放入yy。要解决它,请改用copy(yy[y],xx)。 -
好的,谢谢,让我试试这个。
-
就像答案所说的那样,在循环中使用 make 是一个更好的主意,因为它可以保存副本。我只是想用一条线解决你的问题。
-
只需在循环中移动行:“xx := ...”。