日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Go中切片扩容原理

發布時間:2025/3/21 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go中切片扩容原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

廢話不多說直接看源碼

// src/runtime/slice.go func growslice(et *_type, old slice, cap int) slice { // ...省略部分newcap := old.capdoublecap := newcap + newcapif cap > doublecap {newcap = cap} else {if old.len < 1024 {newcap = doublecap} else {// Check 0 < newcap to detect overflow// and prevent an infinite loop.for 0 < newcap && newcap < cap {newcap += newcap / 4}// Set newcap to the requested cap when// the newcap calculation overflowed.if newcap <= 0 {newcap = cap}}} // ...省略部分 }

四個重要的屬性

  • cap : 需要的容量
  • old.cap : 舊切片的容量
  • newcap : 最終要申請的容量
  • doublecap : old.cap的兩倍

看代碼就知道下方的擴容的機制

  • 當需要的容量cap大于兩倍舊容量doublecap時, 我們申請的新容量就是需要的容量
  • 當需要的容量cap小于兩倍舊容量doublecap時, 判斷是否舊切片的長度小于1024, 如果小于1024, 那么newcap = 兩倍舊cap, 直接翻倍
  • 當舊切片的長度 >= 1024時, 會反復地增加25%,直到新容量newcap超過所需要的容量cap。 其中newcap > 0 是防止int類型溢出, 如果溢出那么就直接newcap = cap(需要的容量)

一點個人思考:
如何求得所需要的容量cap ?
咱們來看兩個例子

第一個 :

func main() {arr := []int{1, 2, 3, 4}fmt.Println("擴容前容量是 : ", cap(arr))arr = append(arr, []int{5, 6, 7, 8, 9}...)fmt.Println("擴容后容量是 : ", cap(arr)) }

擴容前的容量是 4
當我們追加了5個元素之后, 按理來說需要的容量應該是9 對不對 ?
姑且算是cap = 9
在我們上面的growslice函數中, 如果按照cap是9來算的話
最后的newcap 應該是 等于 9
但是打印結果是

再來看另外一個例子

type A struct{}func main() {arr := make([]A, 4)fmt.Println("擴容前容量是 : ", cap(arr))arr = append(arr, []A{{}, {}, {}, {}, {}}...)fmt.Println("擴容后容量是 : ", cap(arr)) }


對于這個自定義切片的結果就是9

結論 : 所以我推測, golang內部對于內置類型, 有著自己的處理方式, 所以第一個例子我們對于int類型的切片append, 應該是進來的cap就是10, 在其他地方做了處理, 可能方便于內存對齊.
對我我們自定義類型的切片就是直接 cap = oldcap + append()函數中追加的容量

總結

以上是生活随笔為你收集整理的Go中切片扩容原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。