英文:
Create a multidimensional array
问题
我如何在Go中创建一个数组的数组?
英文:
How can I create an array of arrays, in Go?
答案1
得分: 7
Building on @Kevin Burke's answer, strictly speaking
a := [][]byte{{1, 2}, {3, 4}}
Is a slice of slices. Which is quite different internally to an array of arrays.
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])
}
}
Internally an array of arrays is just a contiguous bit of memory so it is quite efficient, whereas a slice of slices is more complicated. Each sub slice can be a different size and is allocated in a different place. The slice headers take up extra RAM and use extra indirections to access.
For example creating 100,000 3x3 array of arrays uses up 5.03 MB of RAM whereas creating 100,000 3x3 slices of slices uses up 13.79 MB of RAM.
A slice of slices is much more flexible - each row can have a different size, but if you just want a 2x2 matrix then an array of arrays is a much better choice.
Another difference is that slices are reference types - if you pass a slice to a function you'll be altering the original slice in the function. Arrays are not - if you pass one to a function you'll be making a copy which can be slow, or could be what you want. If you want to modify it then pass a pointer.
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)
}
Which prints
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]]
In general for one dimensional things a slice is pretty much always better than an array. However for multidimensional of a fixed size then arrays of arrays are a better choice.
英文:
Building on @Kevin Burke's answer, strictly speaking
a := [][]byte{{1, 2}, {3, 4}}
Is a slice of slices. Which is quite different internally to an array of arrays.
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])
}
}
Internally an array of arrays is just a contiguous bit of memory so it is quite efficient, whereas a slice of slices is more complicated. Each sub slice can be a different size and is allocated in a different place. The slice headers take up extra RAM and use extra indirections to access.
For example creating 100,000 3x3 array of arrays uses up 5.03 MB of RAM whereas creating 100,000 3x3 slices of slices uses up 13.79 MB of RAM.
A slice of slices is much more flexible - each row can have a different size, but if you just want a 2x2 matrix then an array of arrays is a much better choice.
Another difference is that slices are reference types - if you pass a slice to a function you'll be altering the original slice in the function. Arrays are not - if you pass one to a function you'll be making a copy which can be slow, or could be what you want. If you want to modify it then pass a pointer.
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)
}
Which prints
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]]
In general for one dimensional things a slice is pretty much always better than an array. However for multidimensional of a fixed size then arrays of arrays are a better choice.
答案2
得分: 6
使用嵌套的大括号:
a := [][]byte{{1, 2}, {3, 4}}
英文:
Use nested braces:
a := [][]byte{{1, 2}, {3, 4}}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论