切片类型


67

我目前正在努力完成出色的“围棋之旅”。我使用以下解决方案完成了其中一项练习(#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
}

我不明白为什么我必须使用两次makeuint8类型的语句(请参见摘要中的注释)。这似乎是多余的,但我不知道该怎么做。


可以说,第二行开头可以赋予dx*dyto的容量。通过立即分配所需的内存,是否有助于提高性能?picpic := make([][]uint8, dy, dx*dy)
Arnaud'A

Answers:


33

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

是的,我同意这很冗长,但有必要。第二个make()语句完全独立于第一个。可以争论的是,编译器应该能够从推断类型pic[i],但此时还不行。

另一点:如果在第二种情况下省略了类型,make()语句的外观如何?仍然需要make()来进行实际分配,并能够指定所需的len / capacity。

附带说明,您混合了切片长度。练习表明顶层切片应具有length dy,而不是dx您在代码中输入的长度。


35

明确地说,我们可以使用圆括号将其重写[][]uint8[]([]uint8)uint8)。

使用make内置函数,对于type的切片Tmake(T, n)返回T具有长度n和容量的type的切片n

因此,make([][]uint8, 2)等于make([]([]uint8), 2),它返回类型为的切片,其长度和容量为2的切片uint8,其中每个类型的切片uint8均初始化为其零值(nil长度和容量为零引用)。

多维切片是锯齿状的,类似于多维锯齿状数组

例如,

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

感谢您链接到锯齿状数组!
伤害
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.