创建一个多维数组

huangapple go评论90阅读模式
英文:

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.

Playground link

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.

Here is an example

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.

Playground link

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

fmt.Println(&quot;Slice of Slices&quot;)
b := [][]int{{0, 1}, {2, 3}}
for i := 0; i &lt; 2; i++ {
	for j := 0; j &lt; 2; j++ {
		fmt.Printf(&quot;b[%d][%d] = %d at %p\n&quot;, i, j, b[i][j], &amp;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.

Here is an example

func f1(a [2][2]int) {
	fmt.Println(&quot;I&#39;m a function modifying an array of arrays argument&quot;)
	a[0][0] = 100
}

func f2(b [][]int) {
	fmt.Println(&quot;I&#39;m a function modifying an slice of slices argument&quot;)
	b[0][0] = 100
}

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

	fmt.Println(&quot;Slice of slices&quot;)
	b := [][]int{{0, 1}, {2, 3}}
	fmt.Printf(&quot;Before %v\n&quot;, b)
	f2(b)
	fmt.Printf(&quot;After %v\n&quot;, b)
}

Which prints

Array of arrays
Before [[0 1] [2 3]]
I&#39;m a function modifying an array of arrays argument
After [[0 1] [2 3]]

Slice of slices
Before [[0 1] [2 3]]
I&#39;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}}

huangapple
  • 本文由 发表于 2013年4月27日 11:36:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/16248062.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定