Slice of slices types

删除回忆录丶 提交于 2019-12-03 05:26:16

问题


I'm currently working my way through the excellent Tour of Go. I finished one of the exercises (#45) with the following solution:

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
}

I don't understand why I have to use a make statement with the uint8 type twice (see comments in snippet). That seems redundant but I can't figure out how to do it in an other way.


回答1:


There is no other way to do this in Go.

Yes, I agree it is verbose, but necessary. The second make() statement is entirely independent of the first one. It could be argued that the compiler should be able to infer the type from pic[i], but it doesn't at this point.

Another point: how would the make() statement look if you omitted the type in the second case? The make() is still required to do the actual allocation and to be able to specify the required len/capacity.

As a side note, you mixed up the slice lengths. The exercise states the top level slice should have length dy, not dx as you put in your code.




回答2:


To be explicit, we can use parentheses to rewrite [][]uint8 as []([]uint8): a slice of (slices of type uint8).

Using the make built-in function, for a slice of type T, make(T, n) returns a slice of type T with length n and capacity n.

Therefore, make([][]uint8, 2) is equivalent to make([]([]uint8), 2), it returns a slice, with length and capacity of 2, of slices of type uint8, where each slice of type uint8 is initialized to its zero value (a nil reference with a length and capacity of zero).

Multi-dimensional slices are jagged and are analogous to multi-dimensional jagged arrays.

For example,

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))
    }
}

Output:

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


来源:https://stackoverflow.com/questions/7703251/slice-of-slices-types

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!