成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

開發(fā) 后端
在 Go 中,切片長度 是切片中可用元素的數(shù)量,而 切片容量 是后臺(tái)數(shù)組中的元素?cái)?shù)量。

切片長度與容量在 Go 中很常見。切片長度是切片中可用元素的數(shù)量,而切片容量是從切片中第一個(gè)元素開始計(jì)算的底層數(shù)組中的元素?cái)?shù)量。

Go 中的開發(fā)者經(jīng)常混淆切片長度和容量,或者對它們不夠了解。理解這兩個(gè)概念對于高效處理切片的核心操作,比如切片的初始化、使用 append 添加元素、復(fù)制或切片操作等,至關(guān)重要。對這些概念的誤解可能導(dǎo)致切片的不合理使用,甚至造成內(nèi)存泄漏。

在 Go 中,切片是由數(shù)組支持的。這意味著切片的數(shù)據(jù)以連續(xù)的方式存儲(chǔ)在數(shù)組數(shù)據(jù)結(jié)構(gòu)中。切片還負(fù)責(zé)在底層數(shù)組已滿時(shí)添加元素,或在幾乎為空時(shí)縮減底層數(shù)組。

在內(nèi)部,切片包含指向底層數(shù)組的指針,以及長度和容量。長度表示切片包含的元素?cái)?shù)量,而容量表示底層數(shù)組中的元素?cái)?shù)量,從切片中的第一個(gè)元素開始計(jì)算。讓我們通過一些示例來更清楚地了解這些概念。首先,讓我們使用給定的長度和容量初始化一個(gè)切片:

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

第一個(gè)參數(shù),表示長度,是必須的。但是,第二個(gè)參數(shù)表示容量是可選的。圖1展示了此代碼在內(nèi)存中的結(jié)果。

Figure 1 — 一個(gè)長度為3、容量為6的切片

在這種情況下,make 創(chuàng)建了一個(gè)包含六個(gè)元素的數(shù)組(容量)。但由于長度設(shè)置為3,Go 只初始化了前三個(gè)元素。另外,因?yàn)榍衅?nbsp;[]int 類型,所以前三個(gè)元素被初始化為 int 類型的零值:0。灰色元素已經(jīng)分配但尚未使用。

如果我們打印這個(gè)切片,會(huì)得到長度范圍內(nèi)的元素 [0 0 0]。如果我們將 s[1] 設(shè)為1,切片的第二個(gè)元素會(huì)更新,但不會(huì)影響其長度或容量。圖2說明了這一點(diǎn)。

圖2 — 更新切片的第二個(gè)元素:s[1] = 1

然而,訪問超出長度范圍之外的元素是被禁止的,即使它在內(nèi)存中已經(jīng)分配。例如,s[4] = 0 會(huì)導(dǎo)致以下 panic:

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

我們?nèi)绾问褂们衅S嗟目臻g呢?通過使用內(nèi)置函數(shù) append:

s = append(s, 2)

這段代碼向現(xiàn)有的 s 切片追加了一個(gè)新元素。它使用了第一個(gè)灰色元素(已分配但尚未使用)來存儲(chǔ)元素2,正如圖3所示。

圖3 — 向 s 切片追加一個(gè)元素

切片的長度從3更新為4,因?yàn)楝F(xiàn)在切片包含了四個(gè)元素。現(xiàn)在,如果我們再添加三個(gè)元素以至于后臺(tái)數(shù)組不夠大,會(huì)發(fā)生什么?

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

如果我們運(yùn)行這段代碼,會(huì)看到切片能夠滿足我們的請求:

[0 1 0 2 3 4 5]

因?yàn)閿?shù)組是一個(gè)固定大小的結(jié)構(gòu),在第4個(gè)元素之前,它能夠存儲(chǔ)新的元素。當(dāng)我們想要插入第5個(gè)元素時(shí),數(shù)組已經(jīng)滿了:Go 內(nèi)部會(huì)創(chuàng)建另一個(gè)數(shù)組,將所有元素復(fù)制過去,然后再插入第5個(gè)元素。圖4展示了這個(gè)過程。

圖4 — 因?yàn)槌跏嫉暮笈_(tái)數(shù)組已滿,Go 創(chuàng)建了另一個(gè)數(shù)組并復(fù)制了所有元素。

現(xiàn)在切片引用了新的后臺(tái)數(shù)組。之前的后臺(tái)數(shù)組會(huì)怎樣呢?如果它不再被引用,它最終會(huì)被垃圾收集器(GC)釋放,如果它是在堆上分配的話(我們在錯(cuò)誤#95 “不理解堆棧與堆的區(qū)別”中討論了堆內(nèi)存,并在錯(cuò)誤#99 “不理解GC的工作原理”中討論了GC的工作原理)。

對切片進(jìn)行切片操作會(huì)發(fā)生什么?切片是對數(shù)組或切片進(jìn)行的操作,提供了一個(gè)左閉右開的范圍;第一個(gè)索引是包括的,而第二個(gè)索引是排除的。以下示例展示了影響,并在圖5中顯示了內(nèi)存中的結(jié)果:

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

圖5 — 切片 s1 和 s2 引用相同的后臺(tái)數(shù)組,但長度和容量不同

首先,s1 是一個(gè)長度為3、容量為6的切片。當(dāng)通過對 s1 進(jìn)行切片創(chuàng)建 s2 時(shí),兩個(gè)切片都引用同一個(gè)后臺(tái)數(shù)組。但是,s2 從不同的索引開始,即索引1。因此,它的長度和容量(長度為2,容量為5)與 s1 不同。如果我們更新 s1[1] 或 s2[0],則更改會(huì)作用于同一個(gè)數(shù)組,因此在兩個(gè)切片中都是可見的,如圖6所示。

圖6 — 因?yàn)?s1 和 s2 共享同一個(gè)數(shù)組,更新共同的元素會(huì)使兩個(gè)切片中的更改都可見

現(xiàn)在,如果我們向 s2 添加一個(gè)元素會(huì)發(fā)生什么?以下代碼會(huì)同時(shí)改變 s1 嗎?

s2 = append(s2, 2)

共享的后臺(tái)數(shù)組被修改,但只有 s2 的長度發(fā)生了變化。圖7展示了向 s2 添加元素的結(jié)果。

圖7 — 向 s2 添加元素

s1 仍然是一個(gè)長度為3、容量為6的切片。因此,如果我們打印 s1 和 s2,添加的元素只會(huì)在 s2 中可見:

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

很重要理解這種行為,這樣我們在使用 append 時(shí)就不會(huì)形成錯(cuò)誤的假設(shè)。

注意: 在這些示例中,后臺(tái)數(shù)組是內(nèi)部的,不直接對 Go 開發(fā)者可見。唯一的例外是從現(xiàn)有數(shù)組切片創(chuàng)建切片。

還有最后一件事需要注意:如果我們不斷向 s2 中添加元素,直到后臺(tái)數(shù)組滿為止,內(nèi)存狀態(tài)會(huì)是怎樣的?讓我們再添加三個(gè)元素,以便后臺(tái)數(shù)組沒有足夠的容量:

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

這段代碼導(dǎo)致創(chuàng)建了另一個(gè)后臺(tái)數(shù)組。圖 8 展示了內(nèi)存中的結(jié)果。

圖 8 — 向 s2 添加元素直到后臺(tái)數(shù)組已滿

s1 和 s2 現(xiàn)在引用兩個(gè)不同的數(shù)組。由于 s1 仍然是一個(gè)三長度、六容量的切片,它仍然有一些可用緩沖區(qū),因此它繼續(xù)引用最初的數(shù)組。而且,新的后臺(tái)數(shù)組是通過從 s2 的第一個(gè)索引復(fù)制初始數(shù)組而生成的。這就是為什么新數(shù)組從元素 1 開始,而不是 0。

結(jié)論

總結(jié)一下,切片長度 是切片中可用元素的數(shù)量,而 切片容量 是后臺(tái)數(shù)組中的元素?cái)?shù)量。向一個(gè)已滿的切片(長度 == 容量)添加元素會(huì)導(dǎo)致創(chuàng)建一個(gè)新的后臺(tái)數(shù)組,將之前數(shù)組中的所有元素復(fù)制到新數(shù)組中,并更新切片指向新數(shù)組。

責(zé)任編輯:趙寧寧 來源: 技術(shù)的游戲
相關(guān)推薦

2021-07-13 06:44:04

Go語言數(shù)組

2022-02-09 16:02:26

Go 語言ArraySlice

2024-01-09 16:14:39

RustGo切片

2021-10-15 08:57:40

內(nèi)存容量

2012-06-15 09:56:40

2022-06-02 13:54:04

Go數(shù)組切片

2021-07-30 07:02:34

Slice數(shù)組切片

2021-04-09 10:38:59

Go 語言數(shù)組與切片

2023-10-26 07:09:30

Golangrune字符

2017-08-31 11:28:47

Slice底層實(shí)現(xiàn)

2023-03-29 08:03:53

2023-04-03 08:02:16

切片擴(kuò)容GO

2023-03-13 13:36:00

Go擴(kuò)容切片

2021-07-08 23:53:44

Go語言拷貝

2018-08-20 08:15:50

編程語言Go語言切片

2021-05-12 08:47:54

Go數(shù)組切片

2025-03-04 00:25:55

Go開發(fā)者切片

2021-05-14 08:58:18

非線性安全Go

2022-01-10 13:01:32

指針Struct內(nèi)存

2022-04-06 08:19:13

Go語言切片
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: a级大片免费观看 | 激情91 | 福利网站在线观看 | 一区二区成人 | 色婷婷av一区二区三区软件 | 亚洲一区电影 | 亚洲天堂精品一区 | 黄色大片在线免费观看 | 自拍偷拍3p | 午夜视频在线观看网址 | 99精品久久久久 | 精品视频在线免费观看 | 性做久久久久久免费观看欧美 | 99精品一区二区 | 在线观看免费福利 | 香蕉国产在线视频 | 午夜极品 | 不卡视频在线 | 欧美在线观看一区 | 亚洲午夜精品一区二区三区他趣 | 精品一区二区免费视频 | 日韩精品在线一区 | 国产精品18hdxxxⅹ在线 | 欧美aⅴ| 91成人在线 | 久久久久久久一区 | 国产精品美女久久久久久免费 | 亚洲精品一区中文字幕乱码 | 九九热这里只有精品在线观看 | 中文字幕亚洲区一区二 | 午夜激情一区 | 日韩中文字幕在线播放 | 亚洲男人天堂av | 国产精品一区久久久 | 一区二区三区四区免费视频 | 午夜精品久久久久久不卡欧美一级 | 欧美一区二区激情三区 | 精品国产乱码久久久久久牛牛 | 成人av观看 | 欧美日韩一区二区三区视频 | 在线成人免费视频 |