重學(xué)Go語(yǔ)言之?dāng)?shù)組的具體使用詳解
什么是數(shù)組
什么是數(shù)組?數(shù)組是有固定長(zhǎng)度的相同數(shù)據(jù)類(lèi)型元素的集合, 如下圖所示:

從數(shù)組的定義以及上面的示例圖我們可以得到數(shù)組的三個(gè)特征:
- 固定長(zhǎng)度,數(shù)組的長(zhǎng)度在編譯時(shí)就要確定。
- 每個(gè)元素的數(shù)據(jù)類(lèi)型相同。
- 數(shù)組索引從0開(kāi)始,索引的最大值為數(shù)組長(zhǎng)度減1。
數(shù)組的創(chuàng)建
直接聲明數(shù)組變量,在聲明時(shí)必須指定長(zhǎng)度:
var iArray [2]int var sArray [3]string
上面的代碼中,我們創(chuàng)建了一個(gè)長(zhǎng)度為2,元素?cái)?shù)據(jù)類(lèi)型為int的數(shù)組和一個(gè)長(zhǎng)度為3,元素?cái)?shù)據(jù)類(lèi)型為string的數(shù)組。
聲明后,就可以通過(guò)索引給對(duì)應(yīng)的元素賦值:
iArray[0] = 1 iArray[1] = 2 sArray[0] = "hello" sArray[1] = "world" sArray[2] = "!" fmt.Println(iArray) //輸出 [1,2] fmt.Println(sArray) //輸出 ["hello","world","!"]
也可以在聲明時(shí)通過(guò)花括號(hào){}直接初始化數(shù)組元素的值:
var iArray [2]int = [2]int{1,2}
//花括號(hào)內(nèi)初始化元素?cái)?shù)量可以少于數(shù)組的長(zhǎng)度,后面沒(méi)有初始化的元素會(huì)被賦予該數(shù)據(jù)類(lèi)型的默認(rèn)值
var sArray [4]string = [4]string{"A","B","C"}
如果在聲明時(shí)或者之后沒(méi)有通過(guò)索引給數(shù)組的元素賦值,那么元素的值為對(duì)應(yīng)數(shù)據(jù)類(lèi)型的初始值:
var iArray [3]int var sArray [4]string fmt.Println(iArray) //輸出:[0,0,0] fmt.Println(sArray) //輸出:[]
通知短變量可以讓數(shù)組聲明的更簡(jiǎn)潔:
i := [2]int{1,2}
也可以在聲明數(shù)組不指定數(shù)組長(zhǎng)度,而是通過(guò)...和花括號(hào){}內(nèi)的初始化值讓Go語(yǔ)言自動(dòng)推斷數(shù)組的長(zhǎng)度:
var i = [...]int{1, 2, 3, 4} //數(shù)組長(zhǎng)度為4
訪問(wèn)數(shù)組的元素
通過(guò)索引可以訪問(wèn)數(shù)組中的某個(gè)元素:
fmt.Println(iArray[0])
無(wú)論是給數(shù)組的元素賦值,還是訪問(wèn)數(shù)組的元素都不超過(guò)數(shù)組的長(zhǎng)度,否則會(huì)數(shù)組越界的錯(cuò)誤,數(shù)組的索引從0開(kāi)始,因此數(shù)組的索引取值范圍是0~len-1(len表示數(shù)組的長(zhǎng)度)。
iArray := [2]int{1,2}
sArray := [3]string{"A","B","C"}
iArray[2] = 10 //報(bào)錯(cuò),該數(shù)組索引的取值范圍是0~1
fmt.Println(sArray[10]) // 報(bào)錯(cuò),該數(shù)組索引的取值范圍是0~2
數(shù)組的長(zhǎng)度
Go內(nèi)置的函數(shù)len()可以用于獲得數(shù)組的長(zhǎng)度:
iArray := [4]int{1,2,3,4}
fmt.Println(len(iArray)) // 輸出結(jié)果:4
如何遍歷數(shù)組
遍歷數(shù)組使用for語(yǔ)句,有兩種方式:
使用for語(yǔ)句遍歷數(shù)組:
for i := 0; i < len(iArray); i++ {
fmt.Println(iArray[i])
}
使用for-range遍歷數(shù)組:
for k,v := range iArray {
fmt.Println(k,v)
}
for-range遍歷數(shù)組時(shí),可以獲取數(shù)組的索引和數(shù)組的元素,也可以在遍歷時(shí)選擇忽略索引或者元素值:
for _,v := range iArray { //忽略數(shù)組的索引
fmt.Println(v)
}
for k,_ := range iArray{ //忽略元素
fmt.Println(k)
}
數(shù)組的比較
數(shù)組只能進(jìn)行相等(==)或者不相等(!=)的比較,并且兩個(gè)進(jìn)行比較的數(shù)組要符合以下要求,否則代碼無(wú)法通過(guò)編譯:
- 數(shù)組元素的數(shù)據(jù)類(lèi)型必須一致
- 數(shù)組的長(zhǎng)度必須一致
當(dāng)數(shù)組滿足上面的要求后,如果對(duì)應(yīng)索引元素值相同,則數(shù)組相等,否則不相等:
iArray1 := [2]int{1, 2}
iArray2 := [2]int{1, 2}
if iArray1 == iArray2 {
print("相等")
} else {
print("不相等")
}
//輸出:相等
iArray3 := [2]int{2, 1}
iArray4 := [2]int{1, 2}
if iArray1 == iArray2 {
print("相等")
} else {
print("不相等")
}
//輸出:不相等
查找數(shù)組中的元素
對(duì)于數(shù)組來(lái)說(shuō),要查找數(shù)組中是否存在某個(gè)元素,并返回其對(duì)應(yīng)索引,就要遍歷一個(gè)數(shù)組,并對(duì)每個(gè)元素進(jìn)行比較:
sArray := [5]string{"Java","PHP","Go","Python","JavaScript"}
for index, element := range sArray {
if element == needle {
fmt.Println(index)
}
}
如果我們要查找的元素在數(shù)組的最后一個(gè),那么要遍歷整個(gè)數(shù)組才能查找到,查找元素的時(shí)間復(fù)雜度為O(n)。
將數(shù)組作為函數(shù)參數(shù)
把數(shù)組作為參數(shù)傳遞給函數(shù)時(shí),有幾個(gè)注意的地方:
- 當(dāng)把數(shù)組作為參數(shù)傳給函數(shù)時(shí),Go會(huì)把數(shù)組復(fù)制一份傳給函數(shù),所以數(shù)組作為函數(shù)參數(shù)時(shí)是值傳遞而不是引用傳遞。
- 數(shù)組作為參數(shù),會(huì)被復(fù)制,因此如果傳遞的數(shù)組很大,復(fù)制就會(huì)很耗時(shí)。
- 傳遞給函數(shù)的數(shù)組,其長(zhǎng)度與數(shù)據(jù)類(lèi)型必須函數(shù)形參一致,因此復(fù)用性很差。
func updateArray(haystack [5]int, index int, value int) error {
if index >= len(haystack) {
return errors.New("索引不能超過(guò)數(shù)組長(zhǎng)度")
}
haystack[index] = value
fmt.Println(haystack) //[1 100 3 4 5]
return nil
}
func main() {
iArray := [5]int{1, 2, 3, 4, 5}
updateArray(iArray, 1, 100)
fmt.Println(iArray) // [1 2 3 4 5]
}
上面這個(gè)例子中,我們希望updateArray函數(shù)可以修改我們指定索引的元素?cái)?shù)組,但實(shí)際修改的復(fù)制后數(shù)組,與我們傳給函數(shù)的數(shù)組無(wú)關(guān),解決的辦法是傳遞數(shù)組的指針:
func updateArray(haystack *[5]int, index int, value int) error {
if index >= len(haystack) {
return errors.New("索引不能超過(guò)數(shù)組長(zhǎng)度")
}
haystack[index] = value
fmt.Println(haystack) //[1 100 3 4 5]
return nil
}
func main() {
iArray := [5]int{1, 2, 3, 4, 5}
updateArray(&iArray, 1, 100)
fmt.Println(iArray) // [1 100 3 4 5]
}
雖然傳遞數(shù)組指針可以避免數(shù)組復(fù)制導(dǎo)致的性能問(wèn)題,但是數(shù)組的長(zhǎng)度和元素?cái)?shù)據(jù)類(lèi)型仍然要求一致,這大概就是數(shù)組不怎么被使用的原因吧:
func main() {
iArray := [6]int{1, 2, 3, 4, 5} //把數(shù)組長(zhǎng)度改為6
updateArray(&iArray, 1, 100) //報(bào)錯(cuò)
}
同理,當(dāng)我們把一個(gè)數(shù)組變量賦值另外一個(gè)變量時(shí),Go也是把數(shù)組復(fù)制一份給新的變量,如果想把新的變量指向原來(lái)的數(shù)組,同樣是用數(shù)組的指針:
iArray := [2]int{1,2}
iArray1 := iArray
iArray[0] = 10
fmt.Println(iArray1) //輸出:[10,2]
fmt.Println(iArray) //輸出:[1,2]
iArray2 := &iArray
iArray2[0] = 20;
fmt.Println(iArray2) //輸出:&[20,2]
fmt.Println(iArray) //輸出:[20,2]
二維與多維數(shù)組
Go也支持二維和多維數(shù)組,其創(chuàng)建方式與一維數(shù)組類(lèi)似:
二維數(shù)組:
iArrays := [3][2]string{{"A","B"},{"C","D"},{"E","F"}}
上述二維數(shù)組的結(jié)構(gòu)如下圖所示:

多維數(shù)組:
iArrays := [3][4][2]int{
{
{1, 2},
{3, 4},
{5, 6},
},
{
{7, 8},
{9, 10},
{11, 12},
},
{
{13, 14},
{15, 16},
{17, 18},
},
}上述三維數(shù)組的結(jié)構(gòu)如下圖所示:

小結(jié)
總結(jié)一下,這篇文章主要講了以下幾點(diǎn):
- 數(shù)組是一種固定長(zhǎng)度的相同數(shù)據(jù)類(lèi)型元素的集合,在實(shí)際開(kāi)發(fā)中并不常用,而是作為slice的底層數(shù)據(jù)結(jié)構(gòu)。
- Go支持一維、二維和多維數(shù)組
- 數(shù)組可以進(jìn)行相等或者不相等的比較
- 使用
for或者for-range可以遍歷數(shù)組 - 通過(guò)數(shù)組索引訪問(wèn)元素或者給元素賦值時(shí),都不能超過(guò)數(shù)組的長(zhǎng)度限制。
到此這篇關(guān)于重學(xué)Go語(yǔ)言之?dāng)?shù)組的具體使用詳解的文章就介紹到這了,更多相關(guān)Go語(yǔ)言 數(shù)組內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang快速實(shí)現(xiàn)網(wǎng)頁(yè)截圖的方法
這篇文章主要介紹了golang快速實(shí)現(xiàn)網(wǎng)頁(yè)截圖的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
Go實(shí)現(xiàn)將任何網(wǎng)頁(yè)轉(zhuǎn)化為PDF
在許多應(yīng)用場(chǎng)景中,可能需要將網(wǎng)頁(yè)內(nèi)容轉(zhuǎn)化為?PDF?格式,使用Go編程語(yǔ)言,結(jié)合一些現(xiàn)有的庫(kù),可以非常方便地實(shí)現(xiàn)這一功能,下面我們就來(lái)看看具體實(shí)現(xiàn)方法吧2024-11-11
Go1.18?新特性之多模塊Multi-Module工作區(qū)模式
這篇文章主要介紹了Go1.18?新特性之多模塊Multi-Module工作區(qū)模式,在 Go 1.18之前,建議使用依賴(lài)模塊中的 replace 指令來(lái)處理這個(gè)問(wèn)題,從 Go 1.18開(kāi)始引入了一種同時(shí)處理多個(gè)模塊的新方法,通過(guò)案例給大家詳細(xì)介紹,感興趣的朋友一起看看吧2022-04-04
Go語(yǔ)言實(shí)現(xiàn)字符串切片賦值的方法小結(jié)
這篇文章主要給大家介紹了Go語(yǔ)言實(shí)現(xiàn)字符串切片賦值的兩種方法,分別是在for循環(huán)的range中以及在函數(shù)的參數(shù)傳遞中實(shí)現(xiàn),有需要的朋友們可以根據(jù)自己的需要選擇使用。下面來(lái)一起看看吧。2016-10-10
Go編程中常見(jiàn)錯(cuò)誤和不良實(shí)踐解析
這篇文章主要為大家介紹了Go編程中常見(jiàn)錯(cuò)誤和不良實(shí)踐解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
Golang 使用接口實(shí)現(xiàn)泛型的方法示例
這篇文章主要介紹了Golang 使用接口實(shí)現(xiàn)泛型的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
一文帶你學(xué)會(huì)Go?select語(yǔ)句輕松實(shí)現(xiàn)高效并發(fā)
這篇文章主要為大家詳細(xì)介紹了Golang中select語(yǔ)句的用法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Golang有一定的幫助,需要的可以參考一下2023-03-03

