中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Go?slice切片make生成append追加copy復制的方法

發布時間:2022-06-13 13:49:48 來源:億速云 閱讀:154 作者:iii 欄目:開發技術

這篇文章主要介紹“Go slice切片make生成append追加copy復制的方法”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Go slice切片make生成append追加copy復制的方法”文章能幫助大家解決問題。

加深理解

  • 切片的本質:切片的本質是一個框,框住了一塊連續的內存

  • 切片屬于引用類型,真正的數據都是保存在底層數組里的

  • 切片可以簡單理解為是快捷方式,修改會互相影響

  • 判斷一個切片是否為空,使用len(s) == 0 判斷,不能使用 s==nil 判斷

生成切片 make

上需求:請定義一個長度為5,容量為10的整型切片。

上代碼:

s1 := make([]int,5,10)
fmt.Printf("s1:%v len(s1):%d cap(s1):%d\n", s1, len(s1), cap(s1))

打印結果:

Go?slice切片make生成append追加copy復制的方法

分析:make()函數的第一個參數指定切片的數組類型,第二個參數指定切片的長度,第三個參數指定切片的容量。

更好的理解長度和容量

s1 := make([]int,5,10)
fmt.Printf("s1:%v len(s1):%d cap(s1):%d\n", s1, len(s1), cap(s1))
s2 := make([]int, 0, 10)
fmt.Printf("s2=%v len(s2)=%d cap(s2)=%d\n", s2, len(s2), cap(s2))

打印結果:

Go?slice切片make生成append追加copy復制的方法

分析: 我們可以發現定義切片時元素的個數和長度相關,因為長度就是元素的個數。

容量我們在下面介紹append()時,重點介紹一下。

切片引用類型實戰

上代碼

//切片
s3 := make([]int, 3, 3)
s3 = []int{1, 2, 3}
s4 := s3            //s3 s4都指向同一個底層數組
fmt.Println(s3, s4) //[1 2 3]  [1 2 3]
s3[0] = 1000
fmt.Println(s3, s4) //[1000 2 3] [1 2 3]
fmt.Println("-----")
//數組
a3 := [3]int{1, 2, 4}
a4 := a3
fmt.Println(a3, a4)
a3[0] = 1000
fmt.Println(a3, a4)

打印結果:

Go?slice切片make生成append追加copy復制的方法

分析:通過上面的打印結果我們可以很直觀的看出來,切片引用類型的本質,當切片修改時會互相影響;而數組作為值類型,不會互相影響。

切片的遍歷

和數組一樣,用fori或者for range進行遍歷即可。

s3 := make([]int, 3, 3)
s3 = []int{1, 2, 3}
for i := 0; i < len(s3); i++ {
   fmt.Println(s3[i])
}
for i, v := range s3 {
   fmt.Println(i, v)
}

Go?slice切片make生成append追加copy復制的方法

append

首先,我們定義一個切片

s1 := []string{"北京", "上海", "大連", "佛山"}
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))

打印結果:

Go?slice切片make生成append追加copy復制的方法

分析:我們發現切片的長度和容量都是4

然后,我們使用append()函數追加一個元素

s1 := []string{"北京", "上海", "大連", "佛山"}
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))
s1 = append(s1, "唐山") //切片append()追加之后,
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))

打印結果:

Go?slice切片make生成append追加copy復制的方法

分析:長度由4變成5,我們很好理解;容量為什么會從4變成8呢?

這是Go語言對切片的自動擴容機制。append()追加元素,原來的底層數據容量不夠時,go底層會把底層數組替換,是go語言的一套擴容策略

我后面會單獨寫一篇來講自動擴容策略是如何實現的。歡迎大家持續關注我的專欄Go語言學習專欄

多次追加

多次追加的概念很好理解,就是多次調用append()

舉個栗子:

s1 := []string{"北京", "上海", "大連", "佛山"}
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))
s1 = append(s1, "唐山") //切片append()追加之后,
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))
var s2 []string
s2 = append(s1, "雄安")
fmt.Printf("s2=%v len(s2)=%d cap(s2)=%d\n", s2, len(s2), cap(s2))

打印結果:

Go?slice切片make生成append追加copy復制的方法

分析: s1經過兩次append追加元素,賦值給了s2

追加多個元素

當我們需要追加多個元素時,難道只能像上面這樣多次調用append嗎?

當然不是的。

舉個栗子:

s1 := []string{"北京", "上海", "大連", "佛山"}
s3 := []string{"太原","石家莊"}
var s4 []string
s4 = append(s1,s3...) // ...表示拆開,將切片的值作為追加的元素
fmt.Printf("s4的值:%v",s4)

打印結果:

Go?slice切片make生成append追加copy復制的方法

注意:append的第二個參數,我們傳入了一個切片,需要在切片后寫死...,表示將切片切割,將切片的值作為追加到第一個參數中的元素。

復制切片

下面演示兩種方式:

//定義切片s1
s1 := []int{1, 2, 3}
//第一種方式:直接聲明變量 用=賦值
//s2切片和s1引用同一個內存地址
var s2 = s1
//第二種方式:copy
var s3 = make([]int, 3)
copy(s3, s1)            //使用copy函數將 參數2的元素復制到參數1
fmt.Println(s1, s2, s3) //都是[1 2 3]

打印結果:都返回[1 2 3]

Go?slice切片make生成append追加copy復制的方法

注意:make和:=不能同時使用,這種是錯誤的寫法 :s3 := make([]int, 5)

聰明的小伙伴們是不是提出疑問了呢?

既然結果一樣,為什么要引出copy這個函數呢?

咱們接著往下看,就知道所以然了。

//定義切片s1
s1 := []int{1, 2, 3}
//第一種方式:直接聲明變量 用=賦值
//s2切片和s1引用同一個內存地址
var s2 = s1
//第二種方式:copy
var s3 = make([]int, 3)
copy(s3, s1)            //使用copy函數將 參數2的元素復制到參數1
s1[0] = 11
fmt.Printf("s1:%v s2:%v s3:%v",s1, s2, s3) //s1和s2是[11 2 3] s3是[1 2 3]

打印結果:

Go?slice切片make生成append追加copy復制的方法

分析: 我們發現s1和s2是[11 2 3] s3是[1 2 3],說明copy方法是復制了一份,開辟了新的內存空間,不再引用s1的內存地址,這就是兩者的區別。

刪除元素

注意:刪除切片中的元素 不能直接刪除 可以組合使用分割+append的方式刪除切片中的元素

舉個栗子:比如切除s3中的元素2(下標為1的元素)

s3 := []int{1, 2, 3}
s3 = append(s3[:1], s3[2:]...) //第一個不用拆開 原因是一個作為被接受的一方  是把后面的元素追加到第一個
fmt.Println(s3)

打印結果:

Go?slice切片make生成append追加copy復制的方法

注意:上面代碼段中有我添加的注釋:append()函數中第一個切片不用拆開,原因是一個作為被接受的一方,是把后面的元素追加到第一個切片中。

數組轉切片

a1 := [...]int{1,2,3}
s1 := a1[:]
fmt.Printf("a1類型:%T\ns1類型:%T",a1,s1)

打印結果:

Go?slice切片make生成append追加copy復制的方法

實戰演練

猜想一下下面程序的運行結果:

s1 := make([]int, 5, 10)
for i := 0; i < 10; i++ {
   s1 = append(s1, i)
}
fmt.Println(s1)

.

.

.

打印結果:

Go?slice切片make生成append追加copy復制的方法

分析: 我們靜下心來逐步推導就ok了:

  • s1 := make([]int, 5, 10) 生成的是切片: [0 0 0 0 0]

  • for循環中每次將自增的i值追加到上面的切片中

  • 所以最終打印的結果是:[0 0 0 0 0 0 1 2 3 4 5 6 7 8 9]

關于“Go slice切片make生成append追加copy復制的方法”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

临桂县| 永济市| 遵义市| 石阡县| 元朗区| 东明县| 若羌县| 白城市| 吉林市| 铁岭县| 咸阳市| 棋牌| 九寨沟县| 正定县| 五原县| 呼和浩特市| 武陟县| 壤塘县| 钟祥市| 仪陇县| 莫力| 扬中市| 金乡县| 高碑店市| 渑池县| 南郑县| 洮南市| 灵璧县| 沂水县| 如东县| 铁力市| 锡林郭勒盟| 建阳市| 台南县| 蒙山县| 永定县| 神木县| 祁东县| 遂宁市| 菏泽市| 西峡县|