Arrays Go中的多维数组

Arrays Go中的多维数组,arrays,go,multidimensional-array,Arrays,Go,Multidimensional Array,我正在学习Go,我正在尝试生成一个2d数组[][]int,它在嵌套的for循环中只是将一个值放在点上。我是否总是必须使用make创建具有固定大小的数组,或者是否可以在循环中动态创建 genMap := [][]int{} for i := 0; i < 10; i++ { for j := 0; j < 10; j++ { genMap[i][j] = 1 } } return genMap genMap:=[]int{} 对于i:=0;i

我正在学习Go,我正在尝试生成一个2d数组[][]int,它在嵌套的for循环中只是将一个值放在点上。我是否总是必须使用make创建具有固定大小的数组,或者是否可以在循环中动态创建

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

但这会使错误索引超出范围。因此,我不确定这在Go中是否可行,或者我遗漏了一些关键的内容

您确实遗漏了一些关键的内容--在Go中,切片(从技术上讲,就是您使用语句
genMap:=[][]int{}
创建的内容)默认为零长度。您无法访问
genMap
的任何元素,因为没有可访问的元素,因此任何尝试都会导致索引超出范围错误。作为参考,请查看

有几种方法可以解决这个问题。您可以预先分配切片,在循环中迭代时附加到每个切片,或者为数据选择更方便的数据类型

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

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

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

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)
        }
    }
}
typetwodstruct{
数据[]整数
xSpan int
伊斯潘国际酒店
}
//工厂功能
func NewTwoD(xspan,yspan int)*TwoD{
return&twodd{data:make([]int,xspan*yspan),xspan:xspan,yspan:yspan}
}
func(td*TwoD)Put(x,y,value int){
//也可以在这里进行一些边界检查
td.data[x*td.ySpan+y]=值
}
func(td*TwoD)Get(x,y int)int{
//也可以在这里进行一些边界检查
返回td.data[x*td.ySpan+y]
}
func main(){
genMap:=NewTwoD(10,10)
对于i:=0;i<10;i++{
对于j:=0;j<10;j++{
genMap.Put(i,j,1)
}
}
}


另外,如果你正打算用这些值做线性代数,考虑检查出设计良好、测试良好的代码来帮助你。

也可以看到相关的:优秀的答案,它应该比看起来更值得关注,也许是因为原始问题的分数很低。谢谢
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)
        }
    }
}