網站首頁 編程語言 正文
append函數的使用:
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()函數會創建一個新的slice,它與old slice共享底層內存
創建原理:newSlice = oldSlice[:1+len(x)]
用old slice給new slice進行賦值的方式進行創建,會共享內存。并返回這個new slice。
因此為了保險,我們通常將append返回的內容賦值給原來的slice: x = appen(x,…)
2.如果原來的slice沒有足夠的容量添加內容,則創建一個新的slice,這個slice是copy的old slice。不與old slice共享內存
實例:appendInt()
這個是只能追加一個元素的例子
追加之前,判斷cap(x) 是否足夠,
- 如果足夠則創建的z 大小是 len(x) + 1
- 如果不夠,則創建一個是原來兩倍大的z
func appendInt(x []int, y int) []int { var z []int // 創建一個中間數組 zlen := len(x) + 1 // 準備增加一個元素的位子 // 判斷 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) //創建為原來的兩倍 } 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區別
=
賦值拷貝,會將原來slice的地址拷貝,新舊slice共享內存。
copy(new, old)
函數copy只會將slice內容進行拷貝。
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 數組初始化為1 2 3 4 var test []int = []int{1, 2, 3, 4} //如果我想讓他的 值變成 1 2 3 4 5 6 7 可以使用append 內置函數 /* append主要用于給某個切片(slice)追加元素; 如果該切片存儲空間(cap)足夠,就直接追加,長度(len)變長; 如果空間不足,就會重新開辟內存,并將之前的元素和新的元素一同拷貝進去; 第一個參數為切片,后面是該切片存儲元素類型的可變參數; */ test = append(test, 5) test = append(test, 6) test = append(test, 7) //現在我們得到想要的結果 但是寫了3行 有一個技巧可以直接寫一行解決戰斗 //直接追加一個 slice fmt.Println(test) //當然這個寫肯定是會報錯的。 //cannot use []int literal (type []int) as type int in append //他會告訴你 正常的使用應該是int 類型而不是[]int 類型 test = append(test, []int{5, 6, 7}) //正確的玩法 切記記得加 3個點 test = append(test, []int{5, 6, 7}...) fmt.Println(test) }
總結
原文鏈接:https://blog.csdn.net/zyzyzyzyzyzyzyzyz/article/details/118765740
相關推薦
- 2022-03-06 SQLServer批量插入數據的三種方式及性能對比_C#教程
- 2022-10-19 react封裝Dialog彈框的方法_React
- 2022-05-13 數據結構學習筆記——順序存儲結構實現棧
- 2022-07-17 C++深入講解引用的特點及與指針的區別_C 語言
- 2022-05-15 C++單例類宏定義,方便快速實現單例類
- 2023-02-06 C#實現對文件進行加密保護的示例代碼_C#教程
- 2022-11-03 ios利用RunLoop原理實現去監控卡頓實例詳解_IOS
- 2022-07-01 .NET設計模式之UML類圖介紹_基礎應用
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支