重學(xué)Go語言之?dāng)?shù)組的具體使用詳解
什么是數(shù)組
什么是數(shù)組?數(shù)組是有固定長度的相同數(shù)據(jù)類型元素的集合, 如下圖所示:
從數(shù)組的定義以及上面的示例圖我們可以得到數(shù)組的三個特征:
- 固定長度,數(shù)組的長度在編譯時就要確定。
- 每個元素的數(shù)據(jù)類型相同。
- 數(shù)組索引從0開始,索引的最大值為數(shù)組長度減1。
數(shù)組的創(chuàng)建
直接聲明數(shù)組變量,在聲明時必須指定長度:
var iArray [2]int var sArray [3]string
上面的代碼中,我們創(chuàng)建了一個長度為2
,元素數(shù)據(jù)類型為int
的數(shù)組和一個長度為3
,元素數(shù)據(jù)類型為string
的數(shù)組。
聲明后,就可以通過索引給對應(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ù)組元素的值:
var iArray [2]int = [2]int{1,2} //花括號內(nèi)初始化元素數(shù)量可以少于數(shù)組的長度,后面沒有初始化的元素會被賦予該數(shù)據(jù)類型的默認(rèn)值 var sArray [4]string = [4]string{"A","B","C"}
如果在聲明時或者之后沒有通過索引給數(shù)組的元素賦值,那么元素的值為對應(yīng)數(shù)據(jù)類型的初始值:
var iArray [3]int var sArray [4]string fmt.Println(iArray) //輸出:[0,0,0] fmt.Println(sArray) //輸出:[]
通知短變量可以讓數(shù)組聲明的更簡潔:
i := [2]int{1,2}
也可以在聲明數(shù)組不指定數(shù)組長度,而是通過...
和花括號{}
內(nèi)的初始化值讓Go
語言自動推斷數(shù)組的長度:
var i = [...]int{1, 2, 3, 4} //數(shù)組長度為4
訪問數(shù)組的元素
通過索引可以訪問數(shù)組中的某個元素:
fmt.Println(iArray[0])
無論是給數(shù)組的元素賦值,還是訪問數(shù)組的元素都不超過數(shù)組的長度,否則會數(shù)組越界的錯誤,數(shù)組的索引從0開始,因此數(shù)組的索引取值范圍是0~len-1
(len表示數(shù)組的長度)。
iArray := [2]int{1,2} sArray := [3]string{"A","B","C"} iArray[2] = 10 //報錯,該數(shù)組索引的取值范圍是0~1 fmt.Println(sArray[10]) // 報錯,該數(shù)組索引的取值范圍是0~2
數(shù)組的長度
Go
內(nèi)置的函數(shù)len()
可以用于獲得數(shù)組的長度:
iArray := [4]int{1,2,3,4} fmt.Println(len(iArray)) // 輸出結(jié)果:4
如何遍歷數(shù)組
遍歷數(shù)組使用for
語句,有兩種方式:
使用for
語句遍歷數(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ù)組的元素,也可以在遍歷時選擇忽略索引或者元素值:
for _,v := range iArray { //忽略數(shù)組的索引 fmt.Println(v) } for k,_ := range iArray{ //忽略元素 fmt.Println(k) }
數(shù)組的比較
數(shù)組只能進(jìn)行相等(==
)或者不相等(!=
)的比較,并且兩個進(jìn)行比較的數(shù)組要符合以下要求,否則代碼無法通過編譯:
- 數(shù)組元素的數(shù)據(jù)類型必須一致
- 數(shù)組的長度必須一致
當(dāng)數(shù)組滿足上面的要求后,如果對應(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ù)組中的元素
對于數(shù)組來說,要查找數(shù)組中是否存在某個元素,并返回其對應(yīng)索引,就要遍歷一個數(shù)組,并對每個元素進(jìn)行比較:
sArray := [5]string{"Java","PHP","Go","Python","JavaScript"} for index, element := range sArray { if element == needle { fmt.Println(index) } }
如果我們要查找的元素在數(shù)組的最后一個,那么要遍歷整個數(shù)組才能查找到,查找元素的時間復(fù)雜度為O(n)
。
將數(shù)組作為函數(shù)參數(shù)
把數(shù)組作為參數(shù)傳遞給函數(shù)時,有幾個注意的地方:
- 當(dāng)把數(shù)組作為參數(shù)傳給函數(shù)時,Go會把數(shù)組復(fù)制一份傳給函數(shù),所以數(shù)組作為函數(shù)參數(shù)時是值傳遞而不是引用傳遞。
- 數(shù)組作為參數(shù),會被復(fù)制,因此如果傳遞的數(shù)組很大,復(fù)制就會很耗時。
- 傳遞給函數(shù)的數(shù)組,其長度與數(shù)據(jù)類型必須函數(shù)形參一致,因此復(fù)用性很差。
func updateArray(haystack [5]int, index int, value int) error { if index >= len(haystack) { return errors.New("索引不能超過數(shù)組長度") } 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] }
上面這個例子中,我們希望updateArray
函數(shù)可以修改我們指定索引的元素數(shù)組,但實際修改的復(fù)制后數(shù)組,與我們傳給函數(shù)的數(shù)組無關(guān),解決的辦法是傳遞數(shù)組的指針:
func updateArray(haystack *[5]int, index int, value int) error { if index >= len(haystack) { return errors.New("索引不能超過數(shù)組長度") } 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)致的性能問題,但是數(shù)組的長度和元素數(shù)據(jù)類型仍然要求一致,這大概就是數(shù)組不怎么被使用的原因吧:
func main() { iArray := [6]int{1, 2, 3, 4, 5} //把數(shù)組長度改為6 updateArray(&iArray, 1, 100) //報錯 }
同理,當(dāng)我們把一個數(shù)組變量賦值另外一個變量時,Go也是把數(shù)組復(fù)制一份給新的變量,如果想把新的變量指向原來的數(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ù)組類似:
二維數(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é)一下,這篇文章主要講了以下幾點:
- 數(shù)組是一種固定長度的相同數(shù)據(jù)類型元素的集合,在實際開發(fā)中并不常用,而是作為slice的底層數(shù)據(jù)結(jié)構(gòu)。
- Go支持一維、二維和多維數(shù)組
- 數(shù)組可以進(jìn)行相等或者不相等的比較
- 使用
for
或者for-range
可以遍歷數(shù)組 - 通過數(shù)組索引訪問元素或者給元素賦值時,都不能超過數(shù)組的長度限制。
到此這篇關(guān)于重學(xué)Go語言之?dāng)?shù)組的具體使用詳解的文章就介紹到這了,更多相關(guān)Go語言 數(shù)組內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Go語言中Goroutine退出機(jī)制的原理及使用
goroutine是Go語言提供的語言級別的輕量級線程,在我們需要使用并發(fā)時,我們只需要通過?go?關(guān)鍵字來開啟?goroutine?即可。本文就來詳細(xì)講講Goroutine退出機(jī)制的原理及使用,感興趣的可以了解一下2022-07-07Go語言內(nèi)建函數(shù)cap的實現(xiàn)示例
cap 是一個常用的內(nèi)建函數(shù),它用于獲取某些數(shù)據(jù)結(jié)構(gòu)的容量,本文主要介紹了Go語言內(nèi)建函數(shù)cap的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下2024-08-08簡化Go開發(fā)提高生產(chǎn)力的強(qiáng)大工具及使用詳解
作為?Go?開發(fā)人員,應(yīng)該都知道維持簡潔高效開發(fā)工作流程的重要性,為了提高工作效率和代碼質(zhì)量,簡化開發(fā)流程并自動執(zhí)行重復(fù)性任務(wù)至關(guān)重要,在本文中,我們將探討一些強(qiáng)大的工具和技術(shù),它們將簡化?Go?開發(fā)過程,助力您的編碼之旅2023-10-10關(guān)于golang中死鎖的思考與學(xué)習(xí)
本文主要介紹了關(guān)于golang中死鎖的思考與學(xué)習(xí),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03go語言reflect.Type?和?reflect.Value?應(yīng)用示例詳解
這篇文章主要為大家介紹了go語言reflect.Type?和?reflect.Value?應(yīng)用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09golang 實現(xiàn)struct、json、map互相轉(zhuǎn)化
這篇文章主要介紹了golang 實現(xiàn)struct、json、map互相轉(zhuǎn)化,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12Go語言開發(fā)必知的一個內(nèi)存模型細(xì)節(jié)
這篇文章主要為大家介紹了Go語言開發(fā)必知的一個內(nèi)存模型細(xì)節(jié)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07