我目前正在努力通过优秀的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
}我不明白为什么我必须对uint8类型使用两次make语句(参见代码片段中的注释)。这似乎是多余的,但我想不出用其他方式怎么做。
发布于 2011-10-09 20:53:54
在Go中没有其他方法可以做到这一点。
是的,我同意这是冗长的,但这是必要的。第二个make()语句完全独立于第一个语句。有人可能会认为编译器应该能够从pic[i]推断出类型,但在这一点上它不能。
另一点是:如果在第二种情况下省略了类型,make()语句会是什么样子?make()仍然需要执行实际的分配,并且能够指定所需的长度/容量。
顺便说一句,您混淆了切片长度。本练习说明顶级切片的长度应该是dy,而不是您在代码中放入的dx。
发布于 2011-10-09 22:05:41
明确地说,我们可以使用括号将[][]uint8重写为[]([]uint8):a slice of (类型为uint8的切片)。
使用make内置函数,对于T类型的切片,make(T, n)将返回T类型的切片,长度为n,容量为n。
因此,make([][]uint8, 2)等同于make([]([]uint8), 2),它返回uint8类型的片的长度和容量为2的片,其中每个uint8类型的片都初始化为其零值(长度和容量为零的nil引用)。
多维切片是锯齿状的,类似于多维jagged 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 [] 0https://stackoverflow.com/questions/7703251
复制相似问题