新聞中心
切片(slice)是對數(shù)組的一個連續(xù)片段的引用,所以切片是一個引用類型(因此更類似于 C/ C++ 中的數(shù)組類型,或者 Python 中的 list 類型),這個片段可以是整個數(shù)組,也可以是由起始和終止索引標(biāo)識的一些項的子集,需要注意的是,終止索引標(biāo)識的項不包括在切片內(nèi)。

創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比蘿北網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式蘿北網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋蘿北地區(qū)。費用合理售后完善,十多年實體公司更值得信賴。
Go語言中切片的內(nèi)部結(jié)構(gòu)包含地址、大小和容量,切片一般用于快速地操作一塊數(shù)據(jù)集合,如果將數(shù)據(jù)集合比作切糕的話,切片就是你要的“那一塊”,切的過程包含從哪里開始(切片的起始位置)及切多大(切片的大小),容量可以理解為裝切片的口袋大小,如下圖所示。
圖:切片結(jié)構(gòu)和內(nèi)存分配
從數(shù)組或切片生成新的切片
切片默認(rèn)指向一段連續(xù)內(nèi)存區(qū)域,可以是數(shù)組,也可以是切片本身。
從連續(xù)內(nèi)存區(qū)域生成切片是常見的操作,格式如下:
slice [開始位置 : 結(jié)束位置]
語法說明如下:
- slice:表示目標(biāo)切片對象;
- 開始位置:對應(yīng)目標(biāo)切片對象的索引;
- 結(jié)束位置:對應(yīng)目標(biāo)切片的結(jié)束索引。
從數(shù)組生成切片,代碼如下:
var a = [3]int{1, 2, 3}
fmt.Println(a, a[1:2])其中 a 是一個擁有 3 個整型元素的數(shù)組,被初始化為數(shù)值 1 到 3,使用 a[1:2] 可以生成一個新的切片,代碼運行結(jié)果如下:
[1 2 3] [2]
其中 [2] 就是 a[1:2] 切片操作的結(jié)果。
從數(shù)組或切片生成新的切片擁有如下特性:
- 取出的元素數(shù)量為:結(jié)束位置 - 開始位置;
- 取出元素不包含結(jié)束位置對應(yīng)的索引,切片最后一個元素使用 slice[len(slice)] 獲取;
- 當(dāng)缺省開始位置時,表示從連續(xù)區(qū)域開頭到結(jié)束位置;
- 當(dāng)缺省結(jié)束位置時,表示從開始位置到整個連續(xù)區(qū)域末尾;
- 兩者同時缺省時,與切片本身等效;
- 兩者同時為 0 時,等效于空切片,一般用于切片復(fù)位。
根據(jù)索引位置取切片 slice 元素值時,取值范圍是(0~len(slice)-1),超界會報運行時錯誤,生成切片時,結(jié)束位置可以填寫 len(slice) 但不會報錯。
下面通過實例來熟悉切片的特性。
1) 從指定范圍中生成切片
切片和數(shù)組密不可分,如果將數(shù)組理解為一棟辦公樓,那么切片就是把不同的連續(xù)樓層出租給使用者,出租的過程需要選擇開始樓層和結(jié)束樓層,這個過程就會生成切片,示例代碼如下:
var highRiseBuilding [30]int
for i := 0; i < 30; i++ {
highRiseBuilding[i] = i + 1
}
// 區(qū)間
fmt.Println(highRiseBuilding[10:15])
// 中間到尾部的所有元素
fmt.Println(highRiseBuilding[20:])
// 開頭到中間指定位置的所有元素
fmt.Println(highRiseBuilding[:2])代碼輸出如下:
[11 12 13 14 15]
[21 22 23 24 25 26 27 28 29 30]
[1 2]
代碼中構(gòu)建了一個 30 層的高層建筑,數(shù)組的元素值從 1 到 30,分別代表不同的獨立樓層,輸出的結(jié)果是不同的租售方案。
代碼說明如下:
- 第 8 行,嘗試出租一個區(qū)間樓層。
- 第 11 行,出租 20 層以上。
- 第 14 行,出租 2 層以下,一般是商用鋪面。
切片有點像C語言里的指針,指針可以做運算,但代價是內(nèi)存操作越界,切片在指針的基礎(chǔ)上增加了大小,約束了切片對應(yīng)的內(nèi)存區(qū)域,切片使用中無法對切片內(nèi)部的地址和大小進(jìn)行手動調(diào)整,因此切片比指針更安全、強大。
2) 表示原有的切片
生成切片的格式中,當(dāng)開始和結(jié)束位置都被忽略時,生成的切片將表示和原切片一致的切片,并且生成的切片與原切片在數(shù)據(jù)內(nèi)容上也是一致的,代碼如下:
a := []int{1, 2, 3}
fmt.Println(a[:])a 是一個擁有 3 個元素的切片,將 a 切片使用 a[:] 進(jìn)行操作后,得到的切片與 a 切片一致,代碼輸出如下:
[1 2 3]
3) 重置切片,清空擁有的元素
把切片的開始和結(jié)束位置都設(shè)為 0 時,生成的切片將變空,代碼如下:
a := []int{1, 2, 3}
fmt.Println(a[0:0])代碼輸出如下:
[]
直接聲明新的切片
除了可以從原有的數(shù)組或者切片中生成切片外,也可以聲明一個新的切片,每一種類型都可以擁有其切片類型,表示多個相同類型元素的連續(xù)集合,因此切片類型也可以被聲明,切片類型聲明格式如下:
var name []Type
其中 name 表示切片的變量名,Type 表示切片對應(yīng)的元素類型。
下面代碼展示了切片聲明的使用過程:
// 聲明字符串切片
var strList []string
// 聲明整型切片
var numList []int
// 聲明一個空切片
var numListEmpty = []int{}
// 輸出3個切片
fmt.Println(strList, numList, numListEmpty)
// 輸出3個切片大小
fmt.Println(len(strList), len(numList), len(numListEmpty))
// 切片判定空的結(jié)果
fmt.Println(strList == nil)
fmt.Println(numList == nil)
fmt.Println(numListEmpty == nil)代碼輸出結(jié)果:
[] [] []
0 0 0
true
true
false
代碼說明如下:
- 第 2 行,聲明一個字符串切片,切片中擁有多個字符串。
- 第 5 行,聲明一個整型切片,切片中擁有多個整型數(shù)值。
- 第 8 行,將 numListEmpty 聲明為一個整型切片,本來會在
{}中填充切片的初始化元素,這里沒有填充,所以切片是空的,但是此時的 numListEmpty 已經(jīng)被分配了內(nèi)存,只是還沒有元素。 - 第 11 行,切片均沒有任何元素,3 個切片輸出元素內(nèi)容均為空。
- 第 14 行,沒有對切片進(jìn)行任何操作,strList 和 numList 沒有指向任何數(shù)組或者其他切片。
- 第 17 行和第 18 行,聲明但未使用的切片的默認(rèn)值是 nil,strList 和 numList 也是 nil,所以和 nil 比較的結(jié)果是 true。
- 第 19 行,numListEmpty 已經(jīng)被分配到了內(nèi)存,但沒有元素,因此和 nil 比較時是 false。
切片是動態(tài)結(jié)構(gòu),只能與 nil 判定相等,不能互相判定相等。聲明新的切片后,可以使用 append() 函數(shù)向切片中添加元素。
使用 make() 函數(shù)構(gòu)造切片
如果需要動態(tài)地創(chuàng)建一個切片,可以使用 make() 內(nèi)建函數(shù),格式如下:
make( []Type, size, cap )
其中 Type 是指切片的元素類型,size 指的是為這個類型分配多少個元素,cap 為預(yù)分配的元素數(shù)量,這個值設(shè)定后不影響 size,只是能提前分配空間,降低多次分配空間造成的性能問題。
示例如下:
a := make([]int, 2) b := make([]int, 2, 10) fmt.Println(a, b) fmt.Println(len(a), len(b))
代碼輸出如下:
[0 0] [0 0]
2 2
其中 a 和 b 均是預(yù)分配 2 個元素的切片,只是 b 的內(nèi)部存儲空間已經(jīng)分配了 10 個,但實際使用了 2 個元素。
容量不會影響當(dāng)前的元素個數(shù),因此 a 和 b 取 len 都是 2。
溫馨提示
使用 make() 函數(shù)生成的切片一定發(fā)生了內(nèi)存分配操作,但給定開始與結(jié)束位置(包括切片復(fù)位)的切片只是將新的切片結(jié)構(gòu)指向已經(jīng)分配好的內(nèi)存區(qū)域,設(shè)定開始與結(jié)束位置,不會發(fā)生內(nèi)存分配操作。
本文題目:創(chuàng)新互聯(lián)GO教程:Go語言切片詳解
分享路徑:http://m.fisionsoft.com.cn/article/cojddpj.html


咨詢
建站咨詢
