Golang中Append()使用實例詳解
append函數(shù)的使用:
append可以向一個slice中追加一個元素、多個元素、新的切片
var x []int
x = append(x, 1) // 追加一個元素
x = append(x,2,3,4) //追加多個元素
x = append(x, []int{5,6,7}...) //追加一個新的切片
追加一個切片需要進行解包
append()的原理
1.如果原來slice capacity足夠大的情況下,append()函數(shù)會創(chuàng)建一個新的slice,它與old slice共享底層內(nèi)存
創(chuàng)建原理:newSlice = oldSlice[:1+len(x)]
用old slice給new slice進行賦值的方式進行創(chuàng)建,會共享內(nèi)存。并返回這個new slice。
因此為了保險,我們通常將append返回的內(nèi)容賦值給原來的slice: x = appen(x,…)
2.如果原來的slice沒有足夠的容量添加內(nèi)容,則創(chuàng)建一個新的slice,這個slice是copy的old slice。不與old slice共享內(nèi)存
實例:appendInt()
這個是只能追加一個元素的例子
追加之前,判斷cap(x) 是否足夠,
- 如果足夠則創(chuàng)建的z 大小是 len(x) + 1
- 如果不夠,則創(chuàng)建一個是原來兩倍大的z
func appendInt(x []int, y int) []int {
var z []int // 創(chuàng)建一個中間數(shù)組
zlen := len(x) + 1 // 準(zhǔn)備增加一個元素的位子
// 判斷 x 的cap是否足夠容納新的元素
if zlen <= cap(x) {
// 容量足夠,直接將x拷貝給y
z = x[:zlen]
//如果容量足夠要裝一個z,比x大一個位子,因此要把x后面的空位也拷貝過去
} else {
// x 的容量不夠 需要擴容
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放在最后一個位子
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)容進行拷貝。
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]
補充知識:golang append 小技巧
package main
import (
"fmt"
)
func main() {
//定義個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主要用于給某個切片(slice)追加元素;
如果該切片存儲空間(cap)足夠,就直接追加,長度(len)變長;
如果空間不足,就會重新開辟內(nèi)存,并將之前的元素和新的元素一同拷貝進去;
第一個參數(shù)為切片,后面是該切片存儲元素類型的可變參數(shù);
*/
test = append(test, 5)
test = append(test, 6)
test = append(test, 7)
//現(xiàn)在我們得到想要的結(jié)果 但是寫了3行 有一個技巧可以直接寫一行解決戰(zhàn)斗
//直接追加一個 slice
fmt.Println(test)
//當(dāng)然這個寫肯定是會報錯的。
//cannot use []int literal (type []int) as type int in append
//他會告訴你 正常的使用應(yīng)該是int 類型而不是[]int 類型
test = append(test, []int{5, 6, 7})
//正確的玩法 切記記得加 3個點
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中函數(shù)的健壯性,panic異常處理和defer機制
這篇文章主要為大家詳細介紹了Go中函數(shù)的健壯性,panic異常處理和defer機制的相關(guān)知識,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下2023-10-10

