How can I create an array of arrays, in Go?
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
", 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
", 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
", a)
f1(a)
fmt.Printf("After %v
", a)
fmt.Println("Slice of slices")
b := [][]int{{0, 1}, {2, 3}}
fmt.Printf("Before %v
", b)
f2(b)
fmt.Printf("After %v
", 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.
Use nested braces:
a := [][]byte{{1, 2}, {3, 4}}