本文探討go語言中切片操作后,cap 函數返回值大于切片長度的原因。下例展示了切片長度(len)和容量(cap)在append操作后的變化:
package main import "fmt" func main() { var s []int printSlice(s) // len=0 cap=0 [] s = append(s, 0) printSlice(s) // len=1 cap=1 [0] s = append(s, 1) printSlice(s) // len=2 cap=2 [0 1] s = append(s, 2, 3, 4) printSlice(s) // len=5 cap=6 [0 1 2 3 4] } func printSlice(s []int) { fmt.Printf("len=%d cap=%d %vn", len(s), cap(s), s) }
在添加元素 2, 3, 4 后,len(s) 為 5,但 cap(s) 卻變成了 6。這是因為Go語言的切片底層實現采用了一種增長策略,旨在平衡內存使用和性能。Go語言不會每次都只分配剛好夠用的內存,因為頻繁的內存分配和數據拷貝會降低效率。
Go語言的切片容量增長策略并非線性增長,具體算法在Go源碼中定義,并且可能因版本而異。 一般來說,容量會以一定的比例增長(例如翻倍或按一定公式計算),以減少未來再次append時重新分配內存的頻率。 在例子中,容量從 2 增長到 6,這是一種常見的增長策略,預留了額外的空間,以避免后續添加少量元素時頻繁觸發內存重新分配,從而提升性能。 這符合 cap >= len 的原則,確保切片始終有足夠的容量容納更多元素。
(圖片說明:Go語言切片容量增長示意圖,展示了容量的非線性增長)
立即學習“go語言免費學習筆記(深入)”;
總而言之,cap(s) 為 6 而不是 5,是Go語言為了優化性能而采取的一種預分配策略,并非錯誤。這種策略在大多數情況下能夠提高程序效率,避免頻繁的內存分配和數據拷貝。
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END
喜歡就支持一下吧
相關推薦