爱上开源之golang入门至实战第四章-数组 隐藏的性能陷阱

网友投稿 554 2022-10-20

爱上开源之golang入门至实战第四章-数组 隐藏的性能陷阱

爱上开源之golang入门至实战第四章-数组 隐藏的性能陷阱

4.2.1 数组

var variable_name [SIZE] variable_type或者多维数组var variable_name [SIZE] []variable_type

下面是示例代码

4.2.1.2 初始化

可以直接通过和花括号{}赋值的方式进行初始化;格式如下:

variable_name = [SIZE] variable_type{n1[,n2,n3]}

下面是示例代码

var arr [3]intarr = [3]int{1, 2, 3}

var arr = [3]int{1, 2, 3}arr2 = [2]int{1, 2}

通过指定下标来初始化元素

costs := [5]float32{1:2.0,3:7.0}

初始化数组中 {} 中的元素个数不能大于 [] 中的数字。如果忽略 [] 中的数字不设置数组大小,Go 语言会根据元素的个数来设置数组的大小;

如果数组长度不确定,可以使用 ... 代替数组的长度,编译器会根据元素个数自行推断数组的长度:

var costs = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}或costs := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

以上实例读取了第五个元素。数组元素可以通过索引(位置)来读取(或者修改),索引从 0 开始,第一个元素索引为 0,第二个索引为 1,以此类推;

示例

var arr = [...]int{1, 2, 3} fmt.Printf("%v %T %d\n", arr, arr, unsafe.Sizeof(arr)) var arr2 [2]string arr2 = [2]string{} fmt.Printf("%v %T %d\n", arr2, arr2, unsafe.Sizeof(arr2)) var aa []int16 fmt.Printf("%v %T %d\n", aa, aa, unsafe.Sizeof(aa)) var twoDim [3][3]int16 twoDim = [3][3]int16{[3]int16{1, 2, 3}, [3]int16{4, 5, 6}, [3]int16{7, 8, 9}} fmt.Printf("%v %T %d\n", twoDim, twoDim, unsafe.Sizeof(twoDim)) var twoSlice [3][]int16 twoSlice = [3][]int16{[]int16{1, 2, 3}, []int16{4, 5, 6}, []int16{7, 8, 9}} fmt.Printf("%v %T %d\n", twoSlice, twoSlice, unsafe.Sizeof(twoSlice))

代码结果

=== RUN TestLesson04_1[1 2 3] [3]int 24[ ] [2]string 32[] []int16 24[[1 2 3] [4 5 6] [7 8 9]] [3][3]int16 18[[1 2 3] [4 5 6] [7 8 9]] [3][]int16 72--- PASS: TestLesson04_1 (0.00s)

思考

var twoDim [3][3]int16 和 var twoSlice [3][]int16 有什么区别

4.2.1.3 访问

数组元素可以通过索引(位置)来读取。格式为数组名后加中括号,中括号中为索引的值。例如:

var cost float32 = costs[2]

以上实例读取了数组 costs第3个元素的值。

遍历数组的方法既可以for 条件循环,也可以使用 for-range。这两种 for 结构对于切片(slices)来说也同样适用。

实例

package charpter04import "fmt"import "testing"func TestLesson04_3(t *testing.T) { var n [10]int /* n 是一个长度为 10 的数组 */ var i, j int /* 为数组 n 初始化元素 */ for i = 0; i < len(n); i++ { n[i] = i + 100 /* 设置元素为 i + 100 */ } /* 输出每个数组元素的值 */ for j = 0; j < len(n); j++ { fmt.Printf("Element[%d] = %d\n", j, n[j]) }}

=== RUN TestLesson04_3Element[0] = 100Element[1] = 101Element[2] = 102Element[3] = 103Element[4] = 104Element[5] = 105Element[6] = 106Element[7] = 107Element[8] = 108Element[9] = 109--- PASS: TestLesson04_3 (0.00s)

使用 for-range

=== RUN TestLesson04_4costs[0] = 1000.000000costs[1] = 2.000000costs[2] = 3.400000costs[3] = 7.000000costs[4] = 50.000000costs2[0] = 1000.000000costs2[1] = 2.000000costs2[2] = 3.400000costs2[3] = 7.000000costs2[4] = 50.000000costs3[0] = 0.000000costs3[1] = 2.000000costs3[2] = 0.000000costs3[3] = 7.000000costs3[4] = 0.000000--- PASS: TestLesson04_4 (0.00s)

注意事项

Go中的数组是一个值(valuetype)类型(不像 C/C++ 中是指向首元素的指针),所有的值类型变量,在复制和作为参数传递时,都将产生一次复制动作,如果将数组作为函数的参数类型,则在函数调用时参数数据将发生数据复制,因此,在函数体中无法修改传入的数组的内容,因为函数内操作的只是传入数组的一个副本。可以直接使用=来复制两个数组类型相同的数组对象(包括数组的长度,数组中元素的类型)

func modify(array [5]int) { array[0] = -1 fmt.Printf("%v %T %d\n", array, array, unsafe.Sizeof(array))}func TestLesson04_5(t *testing.T) { array := [5]int{1, 2, 3, 4, 5} modify(array) fmt.Printf("%v %T %d\n", array, array, unsafe.Sizeof(array))}

输出结果

=== RUN TestLesson04_5[-1 2 3 4 5] [5]int 40[1 2 3 4 5] [5]int 40--- PASS: TestLesson04_5 (0.00s)

func TestLesson04_6(t *testing.T) { array := [5]int{1, 2, 3, 4, 5} array[5] = 5 fmt.Printf("%v %T %d\n", array, array, unsafe.Sizeof(array))}

# go-in-practice/code/charpter-01 [go-in-practice/code/charpter-01.test].\lesson03_test.go:176:8: invalid argument: array index 5 out of bounds [0:5]

特别注意

由于数组是值类型(value-type);作为参数或者返回值时;在传递值过程中;会进行内存中的值复制;如果数组的长度过大;会有较大的内存复制上的开销;所以建议此情况下,使用切片或者使用数组的指针对象进行传递

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Mobly- 移动设备测试框架
下一篇:gosiris是一个Golang的actor框架
相关文章

 发表评论

暂时没有评论,来抢沙发吧~