2016-11-04 71 views
0

我讀A Tour of Go和弄不清楚切片的情況下爲什麼切片的能力不`減少[0]`

s = s[:0] 

此操作後,s變爲0的len()cap()不。爲什麼容量不降低?什麼時候會想要使用這個'功能'?

+2

假設您使用該切片作爲增長和縮小的堆棧。你已經彈出了堆棧中的最後一個元素,它的len值爲0.現在你向它推送一些項目。如果我們需要在這種情況下再次開始分配和增加容量,性能將是災難性的。 –

+2

這裏有'[:0]'的用法:[在Golang中寫入緩衝區的開始?](http://stackoverflow.com/a/40234309/1705598)還有相關:[在Go中連接兩個切片](http ://stackoverflow.com/a/40036950/1705598) – icza

+1

偉大的問題!以下博客文章也值得一讀:https://blog.golang.org/go-slices-usage-and-internals –

回答

3

不修改容量的選擇很可能是性能優化。切片基本上是「動態數組」,他們打算提供數組容量無限的抽象。實際上,容量當然受到系統內存的限制,但是如果一個分片容量足夠大,並且您將爲該分配一個新內存以提供該容量(假設它是可用的,如果它不是您的應用程序將會恐慌)。

長度表示切片中的實際可索引項目數,而容量告訴您存在多少底層內存。在執行這些重複操作時,不會立即釋放內存並因此保持分配狀態,這就是爲什麼切片容量保持不變但長度爲零的原因。

總體而言,這可能會導致更好的應用程序性能,因爲如果後續語句將條目附加到片上,內存仍然可用,在實踐中,你通常不需要擔心容量。不過,我建議把它留在你的腦海裏。

當你從某個源讀取數據,並且知道數據的大小,或者至少有一個粗略的想法,並且將它放到一個切片中時,它最相關的時間是imo。在這種情況下,如果使用適當的容量初始化切片,應用程序的性能會更好。如果您沒有提供長度或容量參數(如果僅提供長度,則容量默認爲長度),那麼您可能會發現缺省切片增長效率相當低,或者至少引入效率低下,這很容易避免。