创建一个多维数组

Kev*_*rke 2 go

如何在Go中创建数组数组?

Nic*_*ood 7

严格来说,建立在@Kevin Burke的答案之上

a := [][]byte{{1, 2}, {3, 4}}
Run Code Online (Sandbox Code Playgroud)

一片切片.这与数组数组内部完全不同.

游乐场链接

fmt.Println("Array of Arrays")
a := [2][2]int{{0, 1}, {2, 3}}
for i := 0; i < 2; i++ {
    for j := 0; j < 2; j++ {
        fmt.Printf("a[%d][%d] = %d at %p\n", i, j, a[i][j], &a[i][j])
    }
}

fmt.Println("Slice of Slices")
b := [][]int{{0, 1}, {2, 3}}
for i := 0; i < 2; i++ {
    for j := 0; j < 2; j++ {
        fmt.Printf("b[%d][%d] = %d at %p\n", i, j, b[i][j], &b[i][j])
    }
}
Run Code Online (Sandbox Code Playgroud)

在内部,数组数组只是一个连续的内存位,所以它非常有效,而一片切片则更复杂.每个子切片可以是不同的大小,并且分配在不同的位置.切片标头占用额外的RAM并使用额外的间接访问.

例如,创建100,000个3x3阵列的阵列使用了5.03 MB的RAM,而创建100,000个3x3切片则占用了13.79 MB的RAM.

一片切片更灵活 - 每行可以有不同的大小,但如果你只想要一个2x2矩阵,那么阵列数组是一个更好的选择.

另一个区别是切片是引用类型 - 如果将切片传递给函数,您将改变函数中的原始切片.数组不是 - 如果你将一个传递给一个函数,你将制作一个可能很慢的副本,或者可能是你想要的副本.如果要修改它,则传递指针.

这是一个例子

func f1(a [2][2]int) {
    fmt.Println("I'm a function modifying an array of arrays argument")
    a[0][0] = 100
}

func f2(b [][]int) {
    fmt.Println("I'm a function modifying an slice of slices argument")
    b[0][0] = 100
}

func main() {
    fmt.Println("Array of arrays")
    a := [2][2]int{{0, 1}, {2, 3}}
    fmt.Printf("Before %v\n", a)
    f1(a)
    fmt.Printf("After %v\n\n", a)

    fmt.Println("Slice of slices")
    b := [][]int{{0, 1}, {2, 3}}
    fmt.Printf("Before %v\n", b)
    f2(b)
    fmt.Printf("After %v\n", b)
}
Run Code Online (Sandbox Code Playgroud)

哪个打印

Array of arrays
Before [[0 1] [2 3]]
I'm a function modifying an array of arrays argument
After [[0 1] [2 3]]

Slice of slices
Before [[0 1] [2 3]]
I'm a function modifying an slice of slices argument
After [[100 1] [2 3]]
Run Code Online (Sandbox Code Playgroud)

通常,对于一维事物,切片几乎总是比数组好.但是对于固定大小的多维,那么阵列数组是更好的选择.


Kev*_*rke 6

使用嵌套大括号:

a := [][]byte{{1, 2}, {3, 4}}
Run Code Online (Sandbox Code Playgroud)