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

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

问题描述

我正在通过 A Go之旅学习Go.其中的一项练习要求我创建包含uint8dy行和dx列的2D切片.我目前有效的方法是:

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
}

我认为遍历每个切片以初始化它太冗长.而且,如果切片具有更大的尺寸,则代码将变得笨拙.在Go中有没有一种简便的方法来初始化2D(或n维)切片?

解决方案

没有一种更简洁的方法,您所做的就是正确"的方法.因为切片始终是一维的,但可以组成更高维度的对象.有关更多详细信息,请参见此问题:转到:二维数组的内存表示方式如何.

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

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

还请注意,如果您使用复合文字初始化切片,则会得到免费",例如:

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

是的,这有其局限性,因为您似乎必须枚举所有元素;但是有一些技巧,也就是说,您不必枚举所有值,只需列举不是零的值切片的元素类型的值.有关此操作的更多详细信息,请参见 golang数组初始化中的键控项.

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

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

还要注意,如果您使用数组而不是数组,切片(和字符串):追加"的机制以了解更多详细信息.

转到游乐场上尝试示例.

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天全站免登陆