Golang中Append()使用實(shí)例詳解
append函數(shù)的使用:
append可以向一個(gè)slice中追加一個(gè)元素、多個(gè)元素、新的切片
var x []int x = append(x, 1) // 追加一個(gè)元素 x = append(x,2,3,4) //追加多個(gè)元素 x = append(x, []int{5,6,7}...) //追加一個(gè)新的切片
追加一個(gè)切片需要進(jìn)行解包
append()的原理
1.如果原來slice capacity足夠大的情況下,append()函數(shù)會創(chuàng)建一個(gè)新的slice,它與old slice共享底層內(nèi)存
創(chuàng)建原理:newSlice = oldSlice[:1+len(x)]
用old slice給new slice進(jìn)行賦值的方式進(jìn)行創(chuàng)建,會共享內(nèi)存。并返回這個(gè)new slice。
因此為了保險(xiǎn),我們通常將append返回的內(nèi)容賦值給原來的slice: x = appen(x,…)
2.如果原來的slice沒有足夠的容量添加內(nèi)容,則創(chuàng)建一個(gè)新的slice,這個(gè)slice是copy的old slice。不與old slice共享內(nèi)存
實(shí)例:appendInt()
這個(gè)是只能追加一個(gè)元素的例子
追加之前,判斷cap(x) 是否足夠,
- 如果足夠則創(chuàng)建的z 大小是 len(x) + 1
- 如果不夠,則創(chuàng)建一個(gè)是原來兩倍大的z
func appendInt(x []int, y int) []int { var z []int // 創(chuàng)建一個(gè)中間數(shù)組 zlen := len(x) + 1 // 準(zhǔn)備增加一個(gè)元素的位子 // 判斷 x 的cap是否足夠容納新的元素 if zlen <= cap(x) { // 容量足夠,直接將x拷貝給y z = x[:zlen] //如果容量足夠要裝一個(gè)z,比x大一個(gè)位子,因此要把x后面的空位也拷貝過去 } else { // x 的容量不夠 需要擴(kuò)容 zcap := zlen // 如果xlen == 0 if zcap < 2*len(x) { zcap = 2 * len(x) //創(chuàng)建為原來的兩倍 } z = make([]int, zlen, zcap) copy(z, x) } z[len(x)] = y // 將y放在最后一個(gè)位子 return z }
測試:
func main() { var x, y []int for i := 0; i < 10; i++ { y = appendInt(x, i) fmt.Printf("%d cap=%d\t%v\n", i, cap(y), y) x = y } }
每次容量的變化:
0 cap=1 [0]
1 cap=2 [0 1]
2 cap=4 [0 1 2]
3 cap=4 [0 1 2 3]
4 cap=8 [0 1 2 3 4]
5 cap=8 [0 1 2 3 4 5]
6 cap=8 [0 1 2 3 4 5 6]
7 cap=8 [0 1 2 3 4 5 6 7]
8 cap=16 [0 1 2 3 4 5 6 7 8]
9 cap=16 [0 1 2 3 4 5 6 7 8 9]
拷貝:賦值 copy區(qū)別
=
賦值拷貝,會將原來slice的地址拷貝,新舊slice共享內(nèi)存。
copy(new, old)
函數(shù)copy只會將slice內(nèi)容進(jìn)行拷貝。
var x, y []int x = []int{1, 2, 3, 4} fmt.Println(x, y) // [1 2 3 4] [] y = x y[0] = 0 fmt.Println("y 改后 : ", x, y) //[0 2 3 4] [0 2 3 4]
補(bǔ)充知識:golang append 小技巧
package main import ( "fmt" ) func main() { //定義個(gè)int 數(shù)組初始化為1 2 3 4 var test []int = []int{1, 2, 3, 4} //如果我想讓他的 值變成 1 2 3 4 5 6 7 可以使用append 內(nèi)置函數(shù) /* append主要用于給某個(gè)切片(slice)追加元素; 如果該切片存儲空間(cap)足夠,就直接追加,長度(len)變長; 如果空間不足,就會重新開辟內(nèi)存,并將之前的元素和新的元素一同拷貝進(jìn)去; 第一個(gè)參數(shù)為切片,后面是該切片存儲元素類型的可變參數(shù); */ test = append(test, 5) test = append(test, 6) test = append(test, 7) //現(xiàn)在我們得到想要的結(jié)果 但是寫了3行 有一個(gè)技巧可以直接寫一行解決戰(zhàn)斗 //直接追加一個(gè) slice fmt.Println(test) //當(dāng)然這個(gè)寫肯定是會報(bào)錯(cuò)的。 //cannot use []int literal (type []int) as type int in append //他會告訴你 正常的使用應(yīng)該是int 類型而不是[]int 類型 test = append(test, []int{5, 6, 7}) //正確的玩法 切記記得加 3個(gè)點(diǎn) test = append(test, []int{5, 6, 7}...) fmt.Println(test) }
總結(jié)
到此這篇關(guān)于Golang中Append()使用的文章就介紹到這了,更多相關(guān)Golang Append()詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Go+GoQuery庫實(shí)現(xiàn)頭條新聞采集
在本文中,我們將介紹如何使用Go語言和GoQuery庫實(shí)現(xiàn)一個(gè)簡單的爬蟲程序,用于抓取頭條新聞的網(wǎng)頁內(nèi)容,我們還將使用爬蟲代理服務(wù),提高爬蟲程序的性能和安全性,我們將使用多線程技術(shù),提高采集效率,最后,我們將展示爬蟲程序的運(yùn)行結(jié)果和代碼,需要的朋友可以參考下2023-10-10GoLang中Json?Tag用法實(shí)例總結(jié)
這篇文章主要給大家介紹了關(guān)于GoLang中Json?Tag用法的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-02-02go語言實(shí)現(xiàn)mqtt協(xié)議的實(shí)踐
MQTT是一個(gè)基于客戶端-服務(wù)器的消息發(fā)布/訂閱傳輸協(xié)議。本文主要介紹了go語言實(shí)現(xiàn)mqtt協(xié)議的實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09淺析Go中函數(shù)的健壯性,panic異常處理和defer機(jī)制
這篇文章主要為大家詳細(xì)介紹了Go中函數(shù)的健壯性,panic異常處理和defer機(jī)制的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-10-10