在 Go 中创建 2D 切片的简洁方法是什么? [英] What is a concise way to create a 2D slice in Go?

查看:20
本文介绍了在 Go 中创建 2D 切片的简洁方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过围棋之旅学习围棋.那里的一个练习要求我创建一个包含 uint8dy 行和 dx 列的二维切片.我目前有效的方法是:

a:= make([][]uint8, dy)//初始化一个 dy 切片对于 i:=0;i

我认为遍历每个切片来初始化它太冗长了.如果切片有更多维度,代码将变得笨拙.有没有一种简洁的方法来初始化 Go 中的 2D(或 n 维)切片?

解决方案

没有更简洁的方法,你做的是正确"的方法;因为切片总是一维的,但可以组合起来构造更高维的对象.有关更多详细信息,请参阅此问题:Go:二维数组的内存表示如何.

可以简化的一件事是使用 for range 构造:

a := make([][]uint8, dy)对于 i := 范围 a {a[i] = make([]uint8, dx)}

另请注意,如果您使用 复合文字 初始化您的切片,您将获得免费",例如:

a := [][]uint8{{0, 1, 2, 3},{4, 5, 6, 7},}fmt.Println(a)//输出为 [[0 1 2 3] [4 5 6 7]]

是的,这有其局限性,因为您似乎必须枚举所有元素;但是有一些技巧,即您不必枚举所有值,只需枚举不是 零的值切片元素类型的值.有关这方面的更多详细信息,请参阅 golang 数组初始化中的键项..>

例如,如果您想要一个切片,其中前 10 个元素为零,然后跟随 12,则可以这样创建:

b := []uint{10: 1, 2}fmt.Println(b)//打印 [0 0 0 0 0 0 0 0 0 0 1 2]

另请注意,如果您使用 数组 而不是 切片,它可以很容易地创建:

c := [5][5]uint8{}fmt.Println(c)

输出为:

[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]

对于数组,您不必遍历外部"数组并初始化内部"数组,因为数组不是描述符而是值.有关更多详细信息,请参阅博客文章 数组、切片(和字符串):附加"的机制.>

试试 Go Playground 上的示例.

I am learning Go by going through A Tour of Go. One of the exercises there asks me to create a 2D slice of dy rows and dx columns containing uint8. My current approach, which works, is this:

a:= make([][]uint8, dy)       // initialize a slice of dy slices
for i:=0;i<dy;i++ {
    a[i] = make([]uint8, dx)  // initialize a slice of dx unit8 in each of dy slices
}

I think that iterating through each slice to initialize it is too verbose. And if the slice had more dimensions, the code would become unwieldy. Is there a concise way to initialize 2D (or n-dimensional) slices in Go?

解决方案

There isn't a more concise way, what you did is the "right" way; because slices are always one-dimensional but may be composed to construct higher-dimensional objects. See this question for more details: Go: How is two dimensional array's memory representation.

One thing you can simplify on it is to use the for range construct:

a := make([][]uint8, dy)
for i := range a {
    a[i] = make([]uint8, dx)
}

Also note that if you initialize your slice with a composite literal, you get this for "free", for example:

a := [][]uint8{
    {0, 1, 2, 3},
    {4, 5, 6, 7},
}
fmt.Println(a) // Output is [[0 1 2 3] [4 5 6 7]]

Yes, this has its limits as seemingly you have to enumerate all the elements; but there are some tricks, namely you don't have to enumerate all values, only the ones that are not the zero values of the element type of the slice. For more details about this, see Keyed items in golang array initialization.

For example if you want a slice where the first 10 elements are zeros, and then follows 1 and 2, it can be created like this:

b := []uint{10: 1, 2}
fmt.Println(b) // Prints [0 0 0 0 0 0 0 0 0 0 1 2]

Also note that if you'd use arrays instead of slices, it can be created very easily:

c := [5][5]uint8{}
fmt.Println(c)

Output is:

[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]

In case of arrays you don't have to iterate over the "outer" array and initialize "inner" arrays, as arrays are not descriptors but values. See blog post Arrays, slices (and strings): The mechanics of 'append' for more details.

Try the examples on the Go Playground.

这篇关于在 Go 中创建 2D 切片的简洁方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆