切片types

我目前正在通过优秀的Tour of Go进行工作 。 我用下面的解决方法完成了一个练习(#45):

func Pic(dx, dy int) [][]uint8 { pic := make([][]uint8, dy) /* type declaration */ for i := range pic { pic[i] = make([]uint8, dx) /* again the type? */ for j := range pic[i] { pic[i][j] = uint8((i+j)/2) } } return pic } 

我不明白为什么我必须使用两次使用uint8types的make语句(请参阅代码段中的注释)。 这似乎是多余的,但我不知道如何以其他方式做到这一点。

在Go中没有其他方法可以做到这一点。

是的,我同意这是冗长的,但是必要的。 第二个make()语句完全独立于第一个。 有人可能会认为,编译器应该能够从pic[i]推断出这个types,但是现在还没有。

还有一点:如果在第二种情况下省略了types,那么make()语句将会如何呢? make()仍然需要做实际的分配,并能够指定所需的len /容量。

作为一个侧面说明,你混合了切片的长度。 练习说明顶级切片应该有长度dy ,而不是放在代码中的dx

明确的说,我们可以用括号把[][]uint8改写为[]([]uint8) :一片( uint8types的片)。

使用make内置函数,对于T型片段, make(T, n)返回长度为n ,容量为n T型片段。

因此, make([][]uint8, 2)等同于make([]([]uint8), 2) ,它返回长度和容量为2的slicetypes为uint8的片段,其中片段typesuint8被初始化为零值(一个长度和容量为零的nil参考)。

多维切片是锯齿状的,类似于多维锯齿状arrays 。

例如,

 package main import "fmt" func main() { ss := make([][]uint8, 2) // ss is []([]uint8) fmt.Printf("ss: %T %v %d\n", ss, ss, len(ss)) for i, s := range ss { // s is []uint8 fmt.Printf("ss[%d]: %T %v %d\n", i, s, s, len(s)) } } 

输出:

 ss: [][]uint8 [[] []] 2 ss[0]: []uint8 [] 0 ss[1]: []uint8 [] 0