Go的数组和切片都是一维的。要创建等价的二维数组或切片,就必须定义一个数组的数组, 或切片的切片,就像这样:
type Transform [3][3]float64 // 一个 3x3 的数组,其实是包含多个数组的一个数组。 type LinesOfText [][]byte // 包含多个字节切片的一个切片。
由于切片长度是可变的,因此其内部可能拥有多个不同长度的切片。在我们的 LinesOfText
例子中,这是种常见的情况:每行都有其自己的长度。
text := LinesOfText{ []byte("Now is the time"), []byte("for all good gophers"), []byte("to bring some fun to the party."), }
有时必须分配一个二维数组,例如在处理像素的扫描行时,这种情况就会发生。 我们有两种方式来达到这个目的。一种就是独立地分配每一个切片;而另一种就是只分配一个数组, 将各个切片都指向它。采用哪种方式取决于你的应用。若切片会增长或收缩, 就应该通过独立分配来避免覆盖下一行;若不会,用单次分配来构造对象会更加高效。 以下是这两种方法的大概代码,仅供参考。首先是一次一行的:
// 分配顶层切片。 picture := make([][]uint8, YSize) // 每 y 个单元一行。 // 遍历行,为每一行都分配切片 for i := range picture { picture[i] = make([]uint8, XSize) }
现在是一次分配,对行进行切片:
// 分配顶层切片,和前面一样。 picture := make([][]uint8, YSize) // 每 y 个单元一行。 // 分配一个大的切片来保存所有像素 pixels := make([]uint8, XSize*YSize) // 拥有类型 []uint8,尽管图片是 [][]uint8. // 遍历行,从剩余像素切片的前面切出每行来。 for i := range picture { picture[i], pixels = pixels[:XSize], pixels[XSize:] }