日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Go 中切片(Slice)的長度與容量

來源: 責編: 時間:2023-11-28 17:12:21 245觀看
導讀切片長度與容量在 Go 中很常見。切片長度是切片中可用元素的數(shù)量,而切片容量是從切片中第一個元素開始計算的底層數(shù)組中的元素數(shù)量。Go 中的開發(fā)者經(jīng)常混淆切片長度和容量,或者對它們不夠了解。理解這兩個概念對于高效

切片長度與容量在 Go 中很常見。切片長度是切片中可用元素的數(shù)量,而切片容量是從切片中第一個元素開始計算的底層數(shù)組中的元素數(shù)量。IFl28資訊網(wǎng)——每日最新資訊28at.com

Go 中的開發(fā)者經(jīng)?;煜衅L度和容量,或者對它們不夠了解。理解這兩個概念對于高效處理切片的核心操作,比如切片的初始化、使用 append 添加元素、復制或切片操作等,至關(guān)重要。對這些概念的誤解可能導致切片的不合理使用,甚至造成內(nèi)存泄漏。IFl28資訊網(wǎng)——每日最新資訊28at.com

IFl28資訊網(wǎng)——每日最新資訊28at.com

在 Go 中,切片是由數(shù)組支持的。這意味著切片的數(shù)據(jù)以連續(xù)的方式存儲在數(shù)組數(shù)據(jù)結(jié)構(gòu)中。切片還負責在底層數(shù)組已滿時添加元素,或在幾乎為空時縮減底層數(shù)組。IFl28資訊網(wǎng)——每日最新資訊28at.com

在內(nèi)部,切片包含指向底層數(shù)組的指針,以及長度和容量。長度表示切片包含的元素數(shù)量,而容量表示底層數(shù)組中的元素數(shù)量,從切片中的第一個元素開始計算。讓我們通過一些示例來更清楚地了解這些概念。首先,讓我們使用給定的長度和容量初始化一個切片:IFl28資訊網(wǎng)——每日最新資訊28at.com

s := make([]int, 3, 6) // Three-length, six-capacity slice

第一個參數(shù),表示長度,是必須的。但是,第二個參數(shù)表示容量是可選的。圖1展示了此代碼在內(nèi)存中的結(jié)果。IFl28資訊網(wǎng)——每日最新資訊28at.com

IFl28資訊網(wǎng)——每日最新資訊28at.com

Figure 1 — 一個長度為3、容量為6的切片IFl28資訊網(wǎng)——每日最新資訊28at.com

在這種情況下,make 創(chuàng)建了一個包含六個元素的數(shù)組(容量)。但由于長度設(shè)置為3,Go 只初始化了前三個元素。另外,因為切片是 []int 類型,所以前三個元素被初始化為 int 類型的零值:0?;疑匾呀?jīng)分配但尚未使用。IFl28資訊網(wǎng)——每日最新資訊28at.com

如果我們打印這個切片,會得到長度范圍內(nèi)的元素 [0 0 0]。如果我們將 s[1] 設(shè)為1,切片的第二個元素會更新,但不會影響其長度或容量。圖2說明了這一點。IFl28資訊網(wǎng)——每日最新資訊28at.com

IFl28資訊網(wǎng)——每日最新資訊28at.com

圖2 — 更新切片的第二個元素:s[1] = 1IFl28資訊網(wǎng)——每日最新資訊28at.com

然而,訪問超出長度范圍之外的元素是被禁止的,即使它在內(nèi)存中已經(jīng)分配。例如,s[4] = 0 會導致以下 panic:IFl28資訊網(wǎng)——每日最新資訊28at.com

panic: runtime error: index out of range [4] with length 3

我們?nèi)绾问褂们衅S嗟目臻g呢?通過使用內(nèi)置函數(shù) append:IFl28資訊網(wǎng)——每日最新資訊28at.com

s = append(s, 2)

這段代碼向現(xiàn)有的 s 切片追加了一個新元素。它使用了第一個灰色元素(已分配但尚未使用)來存儲元素2,正如圖3所示。IFl28資訊網(wǎng)——每日最新資訊28at.com

IFl28資訊網(wǎng)——每日最新資訊28at.com

圖3 — 向 s 切片追加一個元素IFl28資訊網(wǎng)——每日最新資訊28at.com

切片的長度從3更新為4,因為現(xiàn)在切片包含了四個元素。現(xiàn)在,如果我們再添加三個元素以至于后臺數(shù)組不夠大,會發(fā)生什么?IFl28資訊網(wǎng)——每日最新資訊28at.com

s = append(s, 3, 4, 5)fmt.Println(s)

如果我們運行這段代碼,會看到切片能夠滿足我們的請求:IFl28資訊網(wǎng)——每日最新資訊28at.com

[0 1 0 2 3 4 5]

因為數(shù)組是一個固定大小的結(jié)構(gòu),在第4個元素之前,它能夠存儲新的元素。當我們想要插入第5個元素時,數(shù)組已經(jīng)滿了:Go 內(nèi)部會創(chuàng)建另一個數(shù)組,將所有元素復制過去,然后再插入第5個元素。圖4展示了這個過程。IFl28資訊網(wǎng)——每日最新資訊28at.com

IFl28資訊網(wǎng)——每日最新資訊28at.com

圖4 — 因為初始的后臺數(shù)組已滿,Go 創(chuàng)建了另一個數(shù)組并復制了所有元素。IFl28資訊網(wǎng)——每日最新資訊28at.com

現(xiàn)在切片引用了新的后臺數(shù)組。之前的后臺數(shù)組會怎樣呢?如果它不再被引用,它最終會被垃圾收集器(GC)釋放,如果它是在堆上分配的話(我們在錯誤#95 “不理解堆棧與堆的區(qū)別”中討論了堆內(nèi)存,并在錯誤#99 “不理解GC的工作原理”中討論了GC的工作原理)。IFl28資訊網(wǎng)——每日最新資訊28at.com

對切片進行切片操作會發(fā)生什么?切片是對數(shù)組或切片進行的操作,提供了一個左閉右開的范圍;第一個索引是包括的,而第二個索引是排除的。以下示例展示了影響,并在圖5中顯示了內(nèi)存中的結(jié)果:IFl28資訊網(wǎng)——每日最新資訊28at.com

s1 := make([]int, 3, 6) // Three-length, six-capacity slices2 := s1[1:3] // Slicing from indices 1 to 3

IFl28資訊網(wǎng)——每日最新資訊28at.com

圖5 — 切片 s1 和 s2 引用相同的后臺數(shù)組,但長度和容量不同IFl28資訊網(wǎng)——每日最新資訊28at.com

首先,s1 是一個長度為3、容量為6的切片。當通過對 s1 進行切片創(chuàng)建 s2 時,兩個切片都引用同一個后臺數(shù)組。但是,s2 從不同的索引開始,即索引1。因此,它的長度和容量(長度為2,容量為5)與 s1 不同。如果我們更新 s1[1] 或 s2[0],則更改會作用于同一個數(shù)組,因此在兩個切片中都是可見的,如圖6所示。IFl28資訊網(wǎng)——每日最新資訊28at.com

IFl28資訊網(wǎng)——每日最新資訊28at.com

圖6 — 因為 s1 和 s2 共享同一個數(shù)組,更新共同的元素會使兩個切片中的更改都可見IFl28資訊網(wǎng)——每日最新資訊28at.com

現(xiàn)在,如果我們向 s2 添加一個元素會發(fā)生什么?以下代碼會同時改變 s1 嗎?IFl28資訊網(wǎng)——每日最新資訊28at.com

s2 = append(s2, 2)

共享的后臺數(shù)組被修改,但只有 s2 的長度發(fā)生了變化。圖7展示了向 s2 添加元素的結(jié)果。IFl28資訊網(wǎng)——每日最新資訊28at.com

IFl28資訊網(wǎng)——每日最新資訊28at.com

圖7 — 向 s2 添加元素IFl28資訊網(wǎng)——每日最新資訊28at.com

s1 仍然是一個長度為3、容量為6的切片。因此,如果我們打印 s1 和 s2,添加的元素只會在 s2 中可見:IFl28資訊網(wǎng)——每日最新資訊28at.com

s1=[0 1 0], s2=[1 0 2]

很重要理解這種行為,這樣我們在使用 append 時就不會形成錯誤的假設(shè)。IFl28資訊網(wǎng)——每日最新資訊28at.com

注意: 在這些示例中,后臺數(shù)組是內(nèi)部的,不直接對 Go 開發(fā)者可見。唯一的例外是從現(xiàn)有數(shù)組切片創(chuàng)建切片。IFl28資訊網(wǎng)——每日最新資訊28at.com

還有最后一件事需要注意:如果我們不斷向 s2 中添加元素,直到后臺數(shù)組滿為止,內(nèi)存狀態(tài)會是怎樣的?讓我們再添加三個元素,以便后臺數(shù)組沒有足夠的容量:IFl28資訊網(wǎng)——每日最新資訊28at.com

s2 = append(s2, 3)s2 = append(s2, 4) // At this stage, the backing is already fulls2 = append(s2, 5)

這段代碼導致創(chuàng)建了另一個后臺數(shù)組。圖 8 展示了內(nèi)存中的結(jié)果。IFl28資訊網(wǎng)——每日最新資訊28at.com

IFl28資訊網(wǎng)——每日最新資訊28at.com

圖 8 — 向 s2 添加元素直到后臺數(shù)組已滿IFl28資訊網(wǎng)——每日最新資訊28at.com

s1 和 s2 現(xiàn)在引用兩個不同的數(shù)組。由于 s1 仍然是一個三長度、六容量的切片,它仍然有一些可用緩沖區(qū),因此它繼續(xù)引用最初的數(shù)組。而且,新的后臺數(shù)組是通過從 s2 的第一個索引復制初始數(shù)組而生成的。這就是為什么新數(shù)組從元素 1 開始,而不是 0。IFl28資訊網(wǎng)——每日最新資訊28at.com

結(jié)論

總結(jié)一下,切片長度 是切片中可用元素的數(shù)量,而 切片容量 是后臺數(shù)組中的元素數(shù)量。向一個已滿的切片(長度 == 容量)添加元素會導致創(chuàng)建一個新的后臺數(shù)組,將之前數(shù)組中的所有元素復制到新數(shù)組中,并更新切片指向新數(shù)組。IFl28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-34929-0.htmlGo 中切片(Slice)的長度與容量

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 理解C++之構(gòu)造函數(shù)

下一篇: 深入探索Python itertools庫的五大常用方法

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 大田县| 福建省| 深州市| 成武县| 阿图什市| 广安市| 收藏| 怀宁县| 连云港市| 罗城| 旅游| 龙泉市| 阿瓦提县| 宁河县| 六枝特区| 新蔡县| 旅游| 鲜城| 双城市| 娄底市| 襄汾县| 桂阳县| 长顺县| 紫云| 石楼县| 临猗县| 鱼台县| 勐海县| 石河子市| 修文县| 桑日县| 和平县| 汉源县| 久治县| 华坪县| 莱芜市| 博湖县| 年辖:市辖区| 宜兴市| 麟游县| 白银市|