Go中的多维数组 [英] multi-dimensional arrays in Go

查看:58
本文介绍了Go中的多维数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习Go,并且正在尝试生成一个2d数组[] [] int,该数组在嵌套的for循环中只是将一个值放到了点.我是否总是必须使用make创建具有固定大小的数组,还是有可能在循环中动态地完成此操作?

I'm learning Go and I'm trying to generate a 2d array [][]int that in a nested for loop just puts a value in the spot. Do I always have to create the array with a fixed size using make or is it possible to have this be done dynamically in the loop?

genMap := [][]int{}
for i := 0; i < 10; i++ {
    for j := 0; j < 10; j++ {
        genMap[i][j] = 1
    }
}
return genMap

这使错误索引超出范围.因此,我不确定是否可以在Go中做到这一点,或者我错过了一些关键的东西

This gives the error index out of range though. So I'm not really sure if this is possible in Go or I'm missing something crucial

推荐答案

实际上,您确实缺少了一些关键的内容-切片(从技术上讲,这是您使用语句 genMap:= [] [] int {} )默认为零长度.您无法访问 genMap 的任何元素,因为没有要访问的元素,因此任何尝试都会导致索引超出范围的错误.作为参考,请查看有关SO的先前答案.

You are indeed missing something crucial--in go, slices (which technically is the thing you are creating with the statement genMap := [][]int{}) default to length zero. You cannot access any elements of genMap because there are none to access, so any attempt to do so results in an index out of range error. For reference, check out this previous answer on SO.

有几种方法可以解决此问题.您可以预分配切片,在遍历循环时附加到每个切片,或者为数据选择更方便的数据类型.

There are a few ways to address this. You could preallocate the slices, append to each slice as you iterate through the loop, or pick a more convenient data type for your data.

正如您提到的,您可以在循环之前简单地将切片分配给已知长度.这可能会导致速度提高,因为您不必每次都需要扩展切片的范围时才在内存中移动值.但是请记住,"2D数组"实际上是一个整数切片,因此每个内部切片( [] int 部分)必须在单独的步骤中分配.您可以在循环中执行此操作:

As you mention, you could simply allocate the slices to the known length before the loop. This could potentially lead to speed improvements because you won't be moving values around in memory every time you have to expand the extent of the slices. Remember, however, that your "2D array" is actually a slice of slice of ints, so each internal slice (the []int part) has to be allocated in a separate step. You can do this in the loop:

genMap := make([][]int, 10)      // Make the outer slice and give it size 10
for i := 0; i < 10; i ++ {
    genMap[i] = make([]int, 10)  // Make one inner slice per iteration and give it size 10
    for j := 0; j < 10; j++ {
        genMap[i][j] = 1
    }
}

查看运行中的代码.

如果您不知道外部或内部切片的大小,这将很有用.如前所述,缺点是调用 append 时可能会占用大量内存,因此效率可能很低.

This is useful if you don't know how large the outer or inner slices will be. The disadvantage, as stated before, is that you might be moving around a lot of memory when you call append, so this could be inefficient.

genMap := [][]int{}             // Make the outer slice with size 0
for i := 0; i < 10; i ++ {
    m := []int{}                // Make one inner slice per iteration with size 0
    for j := 0; j < 10; j++ {
        m = append(m, 1)        // Append to the inner slice
    }
    genMap = append(genMap, m)  // Append to the outer slice
}

查看运行中的代码.

有时,设计满足您的需求但将数据存储在连续切片而不是切片中的结构会更有用.这样可以提高代码的性能和可读性.这样的结构可以定义一些方法来帮助插入和查找索引,例如:

Sometimes it is more useful to design a struct that meets your needs but stores your data in a contiguous slice rather than a slice-of-slices. This could improve performance and readability of your code. Such a struct could have methods defined to help inserting and looking up indices, like so:

type TwoD struct {
    data  []int
    xSpan int
    ySpan int
}

// Factory function
func NewTwoD(xspan, yspan int) *TwoD {
    return &TwoD{data: make([]int, xspan*yspan), xSpan: xspan, ySpan: yspan}
}

func (td *TwoD) Put(x, y, value int) {
    // optionally do some bounds checking here
    td.data[x*td.ySpan+y] = value
}

func (td *TwoD) Get(x, y int) int {
    // optionally do some bounds checking here
    return td.data[x*td.ySpan+y]
}

func main() {
    genMap := NewTwoD(10, 10)
    for i := 0; i < 10; i++ {
        for j := 0; j < 10; j++ {
            genMap.Put(i, j, 1)
        }
    }
}

查看运行中的代码.

此外,如果您打算使用这些值进行线性代数,请考虑检出 Gonum 设计良好,经过测试的代码可为您提供帮助.

Additionally, if you are planning on doing linear algebra with these values, consider checking out Gonum for well-designed, well-tested code to help you out.

这篇关于Go中的多维数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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