Go语言创建、初始化数组的各种方式

Go语言的语法很灵活,以下展示了创建并初始化数组的多种方式:

//数组初始化的各种方式
func arraySliceTest0201() {
	//创建数组(声明长度)
	var array1 = [5]int{1, 2, 3}
	fmt.Printf("array1--- type:%T \n", array1)
	rangeIntPrint(array1[:])

	//创建数组(不声明长度)
	var array2 = [...]int{6, 7, 8}
	fmt.Printf("array2--- type:%T \n", array2)
	rangeIntPrint(array2[:])

	//创建数组切片
	var array3 = []int{9, 10, 11, 12}
	fmt.Printf("array3--- type:%T \n", array3)
	rangeIntPrint(array3)

	//创建数组(声明长度),并仅初始化其中的部分元素
	var array4 = [5]string{3: "Chris", 4: "Ron"}
	fmt.Printf("array4--- type:%T \n", array4)
	rangeObjPrint(array4[:])

	//创建数组(不声明长度),并仅初始化其中的部分元素,数组的长度将根据初始化的元素确定
	var array5 = [...]string{3: "Tom", 2: "Alice"}
	fmt.Printf("array5--- type:%T \n", array5)
	rangeObjPrint(array5[:])

	//创建数组切片,并仅初始化其中的部分元素,数组切片的len将根据初始化的元素确定
	var array6 = []string{4: "Smith", 2: "Alice"}
	fmt.Printf("array6--- type:%T \n", array6)
	rangeObjPrint(array6)
}

//输出整型数组切片
func rangeIntPrint(array []int) {
	for i, v := range array {
		fmt.Printf("index:%d  value:%d\n", i, v)
	}
}

//输出字符串数组切片
func rangeObjPrint(array []string) {
	for i, v := range array {
		fmt.Printf("index:%d  value:%s\n", i, v)
	}
}


<div class="post-text" itemprop="text"> <p>When creating an array in Go, it seems the array will always be zeroed, even if different values will be set right after the initialization, for example when the value should be set to the index in the array.</p> <p>One way to avoid this is to use array literals, such as <code>a = [5]int{0,1,2,3,4}</code>, but it becomes impractical for long arrays. I'm wondering what is the best way to perform the initialization.</p> <p>Surprisingly, the named return function outperforms the composite literal initialization for large arrays.</p> <p>I've created the following benchmark to compare the performance:</p> <pre class="lang-golang prettyprint-override"><code>package main import "testing" const N = 1000000 var result [N]int func arrayLiteral() [N]int { // Replace the 3 dots with the actual value // I copy-pasted the output of an other program to do this return [N]int{0,1,2,3,...,N-1} } func arrayLoopNamedReturn() (a [N]int) { for i := 0; i < N; i++ { a[i] = i } return } func arrayLoop() [N]int { var a [N]int for i := 0; i < N; i++ { a[i] = i } return a } func BenchmarkArrayLoop(b *testing.B) { var r [N]int for n := 0; n < b.N; n++ { r = arrayLoop() } result = r } func BenchmarkArrayLoopNamedReturn(b *testing.B) { var r [N]int for n := 0; n < b.N; n++ { r = arrayLoopNamedReturn() } result = r } func BenchmarkArrayLiteral(b *testing.B) { var r [N]int for n := 0; n < b.N; n++ { r = arrayLiteral() } result = r } </code></pre> <p>Results:</p> <pre><code>N = 10,000 BenchmarkArrayLoop-8 200000 9041 ns/op BenchmarkArrayLoopNamedReturn-8 200000 6327 ns/op BenchmarkArrayLiteral-8 300000 4300 ns/op N = 100,000 BenchmarkArrayLoop-8 10000 191582 ns/op BenchmarkArrayLoopNamedReturn-8 20000 76125 ns/op BenchmarkArrayLiteral-8 20000 62714 ns/op N = 1,000,000 BenchmarkArrayLoop-8 500 2635713 ns/op BenchmarkArrayLoopNamedReturn-8 1000 1537282 ns/op BenchmarkArrayLiteral-8 1000 1854348 ns/op </code></pre> <p>Observations:</p> <ol> <li><p>I did not expect that naming the return value would make a difference for the loop, I thought surely the compiler would do some optimization. For 1,000,000, it becomes faster than the literal initialization.</p></li> <li><p>I expected a linear scaling, I do not understand why it is not the case, for either of the methods.</p></li> </ol> <p>I'm not sure how to explain this, even though it seems to be extremely basic. Any ideas ?</p> <p>Edit: There is an <a href="https://github.com/golang/go/issues/20859" rel="nofollow noreferrer">open issue on Github</a> complaining that naming the return value should not make a difference. I also found this to be a surprising behavior.</p> </div>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页