Go語言中底層陣列和切片的關係以及陣列擴容規則

2022-01-24 06:33:33 字數 1762 閱讀 8334

demo

package main

import (

"fmt"

)func main()

fmt.printf("[%t]len(arr)=%d,cap(arr)=%d \n",arr,len(arr),cap(arr))

// 宣告兩個切片,分別取底層陣列的[1,4],[7:]

s1 := arr[1:4]

fmt.printf("[%t]len(s1)=%d,cap(s1)=%d \n",s1,len(s1),cap(s1))

s2 := arr[7:]

fmt.printf("[%t]len(s2)=%d,cap(s2)=%d \n",s2,len(s2),cap(s2))

// 陣列越界指的是超出陣列長度,例如下面報:panic: runtime error: index out of range [3] with length 3

// s1可以新增元素,新增後s1長度變大,容量不變,同時底層陣列被修改

fmt.printf("[%t]len(s1)=%d,cap(s1)=%d \n",s1,len(s1),cap(s1))

fmt.println(arr)

// s2如果需要新增元素,因為容量不夠,需要進行擴容,開闢新陣列,將原來的7,8,9拷貝過來,再新增乙個20,長度為4,容量為6

fmt.printf("[%t]len(s2)=%d,cap(s2)=%d \n",s2,len(s2),cap(s2))

// 此時修改s2的陣列,底層陣列arr不再受影響

s2[1] = 10

fmt.println(arr)

// 容量為什麼為6?涉及到陣列的擴容規則,舉個例子如下:

ints := int // 原容量oldcap =2

/* if oldcap * 2 < cap else else if oldlen >= 1024

} */

// 上面例子中newcap = 5,int陣列所佔位元組為5*8 = 40,但go語言向記憶體管理模組向作業系統申請的記憶體容量卻沒有40大小的,只有48符合,於是newcap = 48/8 = 6

// go語言記憶體管理模組是16bytes疊加的,8,16,32,48,64,80,96

fmt.printf("[%t]len(ints)=%d,cap(ints)=%d \n",ints,len(ints),cap(ints))

// 例子驗證第二種情況

ints2 := int

// 此時oldcap * 2 > cap ,滿足第二種情況,newcap = 4

fmt.printf("[%t]len(ints2)=%d,cap(ints2)=%d \n",ints2,len(ints2),cap(ints2))

}

列印輸出參考
[int]len(arr)=10,cap(arr)=10 

[int]len(s1)=3,cap(s1)=9

[int]len(s2)=3,cap(s2)=3

[int]len(s1)=4,cap(s1)=9

[0 1 2 3 20 5 6 7 8 9]

[int]len(s2)=4,cap(s2)=6

[0 1 2 3 20 5 6 7 8 9]

[int]len(ints)=5,cap(ints)=6

[int]len(ints2)=3,cap(ints2)=4

process finished with exit code 0

GO語言中的切片

宣告乙個切片int型的切片 var s int 初始化乙個長度為len,容量為cap的切片 s make int,len,cap cap可以省略,省略後cap等於len 也可以簡潔的初始化 s make int len,cap 還可以指定值的建立切片 s int 指定索引值式的建立 s int 索引...

go語言中陣列與切片的區別

一句話總結 切片是動態陣列,注意兩者初始化和函式引數的區別 1 初始化 陣列需要指定大小,不指定也會根據初始化的自動推算出大小,不可改變 陣列 a int a 3 int 切片 a int a make int,5 a make int,5,10 var a int int errora intva...

go語言 陣列和切片

目錄切片 var variable name size variable type 預設值為0eg var ss 10 int var s1 5 int方法一 for i 0 i len arry i 方法二 for index,value range array 儲存了三個一維陣列,每個一位陣列長...