Golang中Append()使用實(shí)例詳解
append函數(shù)的使用:
append可以向一個slice中追加一個元素、多個元素、新的切片
var x []int
x = append(x, 1) // 追加一個元素
x = append(x,2,3,4) //追加多個元素
x = append(x, []int{5,6,7}...) //追加一個新的切片
追加一個切片需要進(jìn)行解包
append()的原理
1.如果原來slice capacity足夠大的情況下,append()函數(shù)會創(chuàng)建一個新的slice,它與old slice共享底層內(nèi)存
創(chuàng)建原理:newSlice = oldSlice[:1+len(x)]
用old slice給new slice進(jìn)行賦值的方式進(jìn)行創(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)存
實(shí)例: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 的容量不夠 需要擴(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放在最后一個位子
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() {
//定義個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)存,并將之前的元素和新的元素一同拷貝進(jìn)去;
第一個參數(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)然這個寫肯定是會報(bào)錯的。
//cannot use []int literal (type []int) as type int in append
//他會告訴你 正常的使用應(yīng)該是int 類型而不是[]int 類型
test = append(test, []int{5, 6, 7})
//正確的玩法 切記記得加 3個點(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)文章
Golang小數(shù)操作指南之判斷小數(shù)點(diǎn)位數(shù)與四舍五入
這篇文章主要給大家介紹了關(guān)于Golang小數(shù)操作指南之判斷小數(shù)點(diǎn)位數(shù)與四舍五入的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2022-03-03
Go語言題解LeetCode1260二維網(wǎng)格遷移示例詳解
這篇文章主要為大家介紹了Go語言題解LeetCode1260二維網(wǎng)格遷移示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
詳解Go語言Slice作為函數(shù)參數(shù)的使用
Slice切片在Go語言中實(shí)質(zhì)是一種結(jié)構(gòu)體類型,本文詳細(xì)的介紹了Go語言Slice作為函數(shù)參數(shù)的使用,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-07-07
Golang使用gin模板渲染base64圖片出現(xiàn)#ZgotmplZ的解決辦法
這篇文章主要介紹了Golang使用gin模板渲染base64圖片出現(xiàn)#ZgotmplZ的的場景復(fù)現(xiàn)和解決辦法,文中通過代碼示例講解的非常詳細(xì),對大家解決問題有一定的幫助,需要的朋友可以參考下2024-05-05

