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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Go中切片扩容原理

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

廢話不多說(shuō)直接看源碼

// 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}}} // ...省略部分 }

四個(gè)重要的屬性

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

看代碼就知道下方的擴(kuò)容的機(jī)制

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

一點(diǎn)個(gè)人思考:
如何求得所需要的容量cap ?
咱們來(lái)看兩個(gè)例子

第一個(gè) :

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

擴(kuò)容前的容量是 4
當(dāng)我們追加了5個(gè)元素之后, 按理來(lái)說(shuō)需要的容量應(yīng)該是9 對(duì)不對(duì) ?
姑且算是cap = 9
在我們上面的growslice函數(shù)中, 如果按照cap是9來(lái)算的話
最后的newcap 應(yīng)該是 等于 9
但是打印結(jié)果是

再來(lái)看另外一個(gè)例子

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


對(duì)于這個(gè)自定義切片的結(jié)果就是9

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

總結(jié)

以上是生活随笔為你收集整理的Go中切片扩容原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。