Go語言學習11 切片擴容

2022-09-22 04:36:13 字數 3868 閱讀 3024

先思考乙個問題:如何給切片新增元素?下面這串**行不行?是錯誤的,不能直接用s1[3]來新增元素,否則會造成索引越界。

package main

import "fmt"

func main()

s1[3] = "shenzhen" //錯誤!索引越界!

fmt.println(s1)

}

func main() 

// s1[3] = "shenzhen" //錯誤!索引越界!

// fmt.println(s1)

fmt.printf("len(s1): %d, cap(s1): %d", len(s1), cap(s1))

fmt.printf("\n")

fmt.printf("len(s1):%d, cap(s1): %d", len(s1), cap(s1))

}

你會發現乙個問題,為什麼變化後的s1容量變成了6呢?

因為原先的切片底層的陣列為3個元素,再加乙個不行了,盛不下,只能再新建一塊記憶體,讓新加入的搬進來。相當於公司搬家一樣,剛開始公司就2個人,乙個老闆乙個前台,後來來了第三個人後公司盛不下了,只能再新建一塊記憶體了。

var s int
s := int{}  // 沒有必要初始化

var s = make(int) // 沒有必要初始化

這麼寫是錯的,不過大概思路是沒什麼問題的。

ss := string
只需要改乙個位置即可,千萬不要笑哈,很真實,就是下面這樣子:在想要新增的切片後,新增三個省略號即可!表示拆開切片,**元素加入

ss := string
貼一下**:

package main

import "fmt"

func main()

// s1[3] = "shenzhen" //錯誤!索引越界!

3、如果底層的陣列不夠新增元素,就會新建立乙個陣列,新建立乙個記憶體區域。

4、匯入新的切片元素時,使用...來分割

舉個例子:

func main() 

}

輸出:

[0]  len:1  cap:1  ptr:0xc0000a8000

[0 1] len:2 cap:2 ptr:0xc0000a8040

[0 1 2] len:3 cap:4 ptr:0xc0000b2020

[0 1 2 3] len:4 cap:4 ptr:0xc0000b2020

[0 1 2 3 4] len:5 cap:8 ptr:0xc0000b6000

[0 1 2 3 4 5] len:6 cap:8 ptr:0xc0000b6000

[0 1 2 3 4 5 6] len:7 cap:8 ptr:0xc0000b6000

[0 1 2 3 4 5 6 7] len:8 cap:8 ptr:0xc0000b6000

[0 1 2 3 4 5 6 7 8] len:9 cap:16 ptr:0xc0000b8000

[0 1 2 3 4 5 6 7 8 9] len:10 cap:16 ptr:0xc0000b8000

從上面的結果可以看出:

切片numslice的容量按照1,2,4,8,16這樣的規則自動進行擴容,每次擴容後都是擴容前的2倍。

有什麼規律呢?

newcap := old.cap

doublecap := newcap + newcap

if cap > doublecap else else

// set newcap to the requested cap when

// the newcap calculation overflowed.

if newcap <= 0

}}

從上面的**可以看出以下內容:

需要注意的是,切片擴容還會根據切片中元素的型別不同而做不同的處理,比如intstring型別的處理方式就不一樣。

首先我們來看乙個問題:

func main() 

b := a

fmt.println(a) //[1 2 3 4 5]

fmt.println(b) //[1 2 3 4 5]

b[0] = 1000

fmt.println(a) //[1000 2 3 4 5]

fmt.println(b) //[1000 2 3 4 5]

}

由於切片是引用型別,所以a和b其實都指向了同一塊記憶體位址。修改b的同時a的值也會發生變化。

go語言內建的copy()函式可以迅速地將乙個切片的資料複製到另外乙個切片空間中,copy()函式的使用格式如下:

copy(destslice, srcslice t)
其中:

舉個例子:

package main

import "fmt"

func main()

a2 := a1

//var a3 int //這麼寫相當於切片a3 == nil為空,肯定是將a1拷貝不進去

var a3 = make(int, 3) //這樣子寫就正確了,其實make函式不用寫後面的容量都是可以的

copy(a3, a1)

fmt.println(a1, a2, a3)

a1[0] = 2000 //更改a1,那麼a2也會發生變化,因為他們兩個用的同一塊記憶體

fmt.println(a1, a2, a3)

}

func main() 

// 要刪除索引為2的元素

fmt.println(a) //[30 31 33 34 35 36 37]

}

1.請寫出下面**的輸出結果。

func main() 

fmt.println(a)

}

2.請使用內建的sort包對陣列var a = [...]int進行排序(附加題,自行查資料解答)。

GO語言學習 切片

切片的長度可以用len獲得,容量由cap獲得.s1 make int,5 len s1 可以得到長度為5,cap s1 可以得到容量為5 s2 make int,5,8 len s2 可以得到長度為5,cap s2 可以得到容量為8 在s1中我沒有用make說明此切片的容量,因此他的容量和長度相等都...

Go語言學習十一 go語言切片

go 語言切片是對陣列的抽象。go 陣列的長度不可改變,在特定場景中這樣的集合就不太適用,go中提供了一種靈活,功能強悍的內建型別切片 動態陣列 與陣列相比切片的長度是不固定的,可以追加元素,在追加時可能使切片的容量增大。你可以宣告乙個未指定大小的陣列來定義切片 var identifier typ...

go語言學習筆記 切片

理解 建立切片 1.make函式,語法 make 型別,長度,容量 s make int,3,5 切片s可以訪問3個元素,底層陣列擁有5個元素 注意 不允許建立長度小於容量的切片 2.建立乙個陣列的切片 arr string slice arr 1 3 hi go 從索引1到3位置的元素,不包含右邊...