多维数组介绍
1、多维静态数组
array := [][]byte{}
在函数中传递数组是非常昂贵的行为,因为在函数之间传递变量永远是传递值,所以如果变量是数组,那么意味着传递整个数组,即使它很大很大很大。。。
举个栗子,创建一个有百万元素的整形数组,在64位的机器上它需要8兆的内存空间,来看看我们声明它和传递它时发生了什么:
复制代码 代码如下:
var array [1e6]int
foo(array)
func foo(array [1e6]int) {
…
}
每一次 foo 被调用,8兆内存将会被分配在栈上。一旦函数返回,会弹栈并释放内存,每次都需要8兆空间。
Go 语言当然不会这么傻,有更好的方法来在函数中传递数组,那就是传递指向数组的指针,这样每次只需要分配8字节内存:
复制代码 代码如下:
var array [1e6]int
foo(&array)
func foo(array *[1e6]int){
…
}
但是注意如果你在函数中改变指针指向的值,那么原始数组的值也会被改变。幸运的是 slice(切片)可以帮我们处理好这些问题,来一起看看。
2、多维动态数组
slice := [][]byte{}
创建二维数据组
slic := [][]int{{10}, {21, 22}}
fmt.Println("slic", slic)
fmt.Println("slic[0]:", slic[0])
fmt.Println("slic[1]:", slic[1])
fmt.Println("slic[0][0]", slic[0][0])
运行结果:
slic [[10] [21 22]]
slic[0]: [10]
slic[1]: [21 22]
slic[0][0] 10
成功: 进程退出代码 0.
append()方法,比如我们现在对 slice[0] 增加一个元素,由于slice[0]分配空间已满需重新分配,则重建slice[0];slice[1]不受影响
func MulitSliceAppend() {
S_0 := []int{11}
S_1 := []int{20, 21}
M_Slice := [][]int{S_0, S_1}
fmt.Println("初始化 ", ":M_Slice", M_Slice)
S_0[0] = 10
fmt.Println("S_0 更改", ":M_Slice", M_Slice)
fmt.Println("---------------------------------------------------------")
M_Slice[0] = append(M_Slice[0], 11)
fmt.Println("Append ", ":M_Slice", M_Slice)
S_0[0] = 11
S_1[0] = 11
fmt.Println("S_0 1更改", ":M_Slice", M_Slice)
}
运行结果:
初始化 :M_Slice [[11] [20 21]]
S_0 更改 :M_Slice [[10] [20 21]]
---------------------------------------------------------
Append :M_Slice [[10 11] [20 21]]
S_0 1更改 :M_Slice [[10 11] [11 21]]
成功: 进程退出代码 0.
通过上述操作可以看到,若未重新分配地址,更改初始化切片时,多维切片值也会随之相应的变化;对slice[0]Append之后,对S_0值更改slice[0]不随之变化,说明slice[0]重新分配;对S_1值更改slice[1]随之变化,说明slice[1]未重新分配。
有疑问加站长微信联系(非本文作者)