Go 語言基礎系列(四):內置容器
什麼是內置容器?
當數據的量較少時,通過常量和變量進行存儲可以進行計算,但是當我們編寫更加複雜、數據量更多的程序時,需要對數據進行相應的存儲,便是本篇的主題——內置容器
上面我們介紹了內置容器的作用以及由來,那麼 Go 語言主要包括哪些內置容器呢?
思維邏輯圖如下:
Go 語言中內置容器主要包括:數組、切片和映射三種內置容器,下面我們對這三種容器進行相應的介紹
** 數組 **
01
** 數組的聲明 **
數組是一種用於存儲一組相同類型而且長度固定的數據的數據結構
數組必須先聲明後使用,而且在聲明時必須指明數組的大小和數據類型
標準格式:var 數組名 [數組長度] 數據類型
例如:聲明一個名爲 city,數據類型爲 string,長度爲 16 的數組
結果如下:
解釋:由於我們還未對數組賦值,所以結果爲空數組
02
** 數組的初始化 **
初始化是指在聲明的同時進行賦值,數組的初始化即是對數組在聲明的同時進行賦值
標準格式:var 數組名 = [數組長度] 數據類型 {數組的每一項}
例如:聲明一個名爲 nums,長度爲 3,數據類型爲 int 的數組,並且數組的每一項分別賦值爲 1,2,3
結果如下:
解釋:由於我們在聲明的同時便對數組進行了賦值,所以結果不再是空數組
03
** 操作數組 **
由於數組聲明後大小固定,不能刪除,只能修改,所以數組的操作主要包括:選讀取數組中的某個數據、修改數組中的某個數據以及遍歷整個數組
1)讀取數組中的某個數據和修改數組中的某個數據
數組數據的讀取主要通過下標的方式,下標從 0 開始,到數組長度減 1 結束
示例:初始化了一個名爲 nums 的數組,通過下標讀取它的第 1 個元素,並將其修改
結果如下:
2)遍歷數組
像 1)中那樣可以實現對數組的部分遍歷,但是當對整個數組進行遍歷時,就不夠方便和簡潔;故可以通過上篇循環控制的 for 循環進行遍歷
示例如下:
結果如下:
上面的方式同樣可以實現對數組的遍歷,但是在 Go 語言中,引入了一個非常常用的關鍵字:range,可以和 for 搭配實現對數組、切片和映射的遍歷
示例如下:
結果如下:
** 切片 **
01
** 切片的聲明及初始化 **
與數組相似,切片也是對同種數據類型元素的連續集合,但是切片自身不存儲任何元素,它僅僅是對現有數組的引用(下文有證明)
切片的聲明方式主要有三種:1. 從數組聲明一個切片;2. 從切片聲明一個新的切片;3. 直接聲明一個新的切片;
1)從數組聲明一個切片
格式如下:數組名 [起始位置:結束位置]
示例如下:
結果如下:
解釋:首先聲明瞭一個名爲 nums 的數組,然後通過數組聲明瞭一個名爲 numSlice 的切片
注:1. 聲明的切片包括的元素不包含結束位置對應的數組元素;2. 本例還對上面提到的切片是數組的引用進行了證明,由於內存中數組的地址爲第一個元素的地址,所以對比數組的第一個元素地址和切片的第一個元素地址,發現地址相同,故切片是數組的引用;
2)從切片聲明一個切片
格式如下:切片名 [起始位置:結束位置]
示例如下:
結果如下:
解釋:從切片 numSlice 聲明瞭一個新的切片 numSlice2,而且發現 numSlice 切片仍然是數組的引用
注:以上兩種聲明生成切片的方式,由於歸根到底都是通過一個已經初始化後的數組進行聲明,所以聲明的同時就完成了賦值,故只需聲明便可生成帶有數據的切片
3)直接聲明一個切片
標準格式:var 切片名 [] 數據類型
注:直接聲明一個切片的格式與聲明也給數組的格式的區別:[] 中是否包括了長度,有則爲數組,空則爲切片
示例如下:
結果如下:
a) 和數組相似的初始化方式:
結果如下:
b) make() 函數初始化
使用 make() 函數初始化,需要先以直接聲明一個切片的方式聲明一個切片
格式如下**:****make([] 數據類型, 切片長度,切片容量)**
**注:**長度:切片中實際存在的元素的個數,len() 函數可以獲取當前切片的長度;容量:從切片的第一個元素開始到其引用的底層數組中的最後一個元素的個數,cap() 函數可以獲取當前切片的容量;
切片長度容量示例如下:
切片長度容量結果如下:
解釋:a. 切片的長度:由於切片不包括聲明時的結束位置,所以 numSlice 切片只包括下標爲 0 和 1 的元素,故長度爲 2;b. 切片的容量:從切片的第一個元素 1,到底層數組的最後一個元素 3 分別爲:1,2,3,個數爲 3,故容量爲 3;
上面是對切片的長度和容量進行了相應的介紹,下面我們迴歸到 make() 函數的切片初始化
示例如下:
結果如下:
解釋:切片在初始化後,自動填充了該數據類型的默認值:int 默認值爲 0,string 默認值爲空字符串,bool 爲 false;
**02
**
**** 操作切片 ****
由於切片少了固定長度的約束,所以可以對切片進行增刪改查,查即爲遍歷
- 爲切片增加元素
爲切片增加元素可以通過 append() 函數完成,當切片的長度等於切片容量時,下一次使用 append() 函數添加元素,容量會以 2 倍的方式擴容。但是要注意:當切片的長度小於數組的長度時,而且切片的最後一個元素的下標不等於數組的最後一個元素的下標時,對切片進行增加元素操作時,會對底層數組的元素進行修改
示例如下:
結果如下:
注意:a) 當爲 numSlice 增加元素 4 時,由於切片的長度小於數組的長度,而且切片的最後一個元素的下標爲 1,不等於數組的最後一個元素的下標 2,所以對切片增加 4 時,會導致數組 num 的修改變爲 [1,2,4];b) 當切片的長度等於切片容量時,下一次使用 append() 函數添加元素,容量會以 2 倍的方式擴容,所以當增加 5 時切片擴容爲 6;c) 當切片增加 5 時,由於切片長度已經等於數組的長度,所以不會再改變新的數組的元素值;
- 爲切片刪除元素
Go 語言中沒有提供直接刪除元素的方法,但是可以通過 append 函數完成
示例如下:
結果如下:
解釋:示例中 append(numSlice[0:1],numSlice[2:]...) 是一種簡寫方式,等效於 append(numSlice[0:1],numSlice[2],numSlice[3])
那麼刪除切片的元素時,會影響底層數組的元素值嗎?
示例如下:
結果如下:
所以:刪除切片元素時,會導致底層數組的元素值的變化
剛剛介紹的是刪除單個或者幾個元素,我們可以通過拼接的方式刪除,當要全部刪除時,可以直接將切片的起始位置和結束位置均設爲 0 實現
3) 爲切片修改元素
示例如下:
結果如下:
注:修改切片的元素可以通過切片的下標直接進行修改,但是注意修改切片的元素也會對底層數組進行修改
4) 遍歷切片
切片的遍歷和數組的遍歷相似,通過 for 循環和 range 關鍵字完成
示例如下:
結果如下:
** 映射 **
01
** 映射的聲明及初始化 **
1)映射是一種無序的鍵值對集合
格式如下:**var map [鍵數據類型] 值數類型 **
結果如下:
2)映射的初始化
映射的初始化有兩種方式:聲明時進行賦值初始化和使用 make() 函數初始化
a)聲明時進行初始化
結果如下:
b) make() 函數初始化
格式如下:make(map[鍵數據類型] 值數據類型,map 容量)
默認容量爲 0(會擴容),map 的長度可以通過 len() 函數獲取,不能通過 cap() 函數獲取 map 容量
結果如下:
**02
**
**** 操作映射 ****
1)增加鍵值對和修改鍵值對
結果如下:
2)刪除鍵值對
map 中刪除鍵值對可以通過 delete() 函數實現
格式如下:delete(map 名, 鍵)
結果如下:
3)遍歷鍵值對
map 的遍歷和數組以及切片的遍歷方式一樣,通過 for 循環和 range 關鍵字實現
結果如下:
到此關於 Golang 內置容器的分享就結束了~
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/YXso7DqYOumR2tHwPIWRkg