切片类型的切片

发布于 2024-12-09 01:30:19 字数 493 浏览 1 评论 0原文

我目前正在完成精彩的 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 语句两次(请参阅注释在片段中)。这似乎是多余的,但我不知道如何以其他方式做到这一点。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

最美不过初阳 2024-12-16 01:30:19

明确地说,我们可以使用括号将 [][]uint8 重写为 []([]uint8): (slices of type uint8< /代码>)。

使用 make 内置函数,对于 T 类型的切片,make(T, n) 返回一个 T 类型的切片,长度为 n,容量为 n

因此,make([][]uint8, 2)相当于make([]([]uint8), 2),它返回一个切片,其长度和uint8 类型切片的容量为 2,其中 uint8 类型的每个切片都初始化为零值(nil< /code> 长度和容量为的引用 零)。

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

例如,

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

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
苏别ゝ 2024-12-16 01:30:19

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

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

另一点:如果在第二种情况下省略类型,make() 语句会是什么样子?仍然需要 make() 来进行实际分配并能够指定所需的长度/容量。

作为旁注,您混淆了切片长度。该练习指出,顶级切片的长度应为 dy,而不是您在代码中输入的 dx

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.

咽泪装欢 2024-12-16 01:30:19

您可以像这样初始化切片切片:

matrix2D := [][]int8{
    {1, 2, 3},
    {4, 5, 6},
}
fmt.Println(matrix2D) // [[1 2 3] [4 5 6]]

You can initialize slice of slices like that:

matrix2D := [][]int8{
    {1, 2, 3},
    {4, 5, 6},
}
fmt.Println(matrix2D) // [[1 2 3] [4 5 6]]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文