數(shù)組,是用來存儲集合數(shù)據(jù)的。這種場景非常多,我們編碼的過程中,都少不了要讀取或者存儲數(shù)據(jù)。當(dāng)然除了數(shù)組之外,我們還有切片、Map映射等數(shù)據(jù)結(jié)構(gòu)可以幫我們存儲數(shù)據(jù),但是數(shù)組是它們的基礎(chǔ)。
內(nèi)部實(shí)現(xiàn)
要想更清晰地了解數(shù)組,我們先得了解它的內(nèi)部實(shí)現(xiàn)。數(shù)組是長度固定的數(shù)據(jù)類型,必須存儲一段相同類型的元素,而且這些元素是連續(xù)的。我們這里強(qiáng)調(diào)固定長度,可以說這是和切片最明顯的區(qū)別。
數(shù)組存儲的類型可以是內(nèi)置類型,比如整型或者字符串;也可以是自定義的數(shù)據(jù)結(jié)構(gòu)。因?yàn)槭沁B續(xù)的,所以索引比較好計算,所以我們可以很快地索引數(shù)組中的任何數(shù)據(jù)。
這里的索引,一直都是0、1、2、3這樣的,因?yàn)槠湓仡愋拖嗤?。我們也可以使用反射,獲取類型占用大小,進(jìn)行移位,獲取相應(yīng)的元素。這部分在說到反射的時候,我們再講。
聲明和初始化
數(shù)組的聲明和初始化,和其他類型差不多。聲明的原則是:
指明存儲數(shù)據(jù)的類型。
存儲元素的數(shù)量,也就是數(shù)組長度。
var array [5]int
以上我們聲明了一個數(shù)組array
,但是我們還沒有對他進(jìn)行初始化,這時候數(shù)組array
里面的值,是對應(yīng)元素類型的零值。也就是說,現(xiàn)在這個數(shù)組是 5 個 0 ,這和我們Java不一樣,Java里是null。
數(shù)組一旦聲明后,其元素類型和大小都不能變了,如果還需要存儲更多的元素怎么辦?那么只能通過創(chuàng)建一個新的數(shù)組,然后把原來數(shù)組的數(shù)據(jù)復(fù)制過去。
剛剛聲明的數(shù)組已經(jīng)被默認(rèn)的元素類型零值初始化了,如果我們再次進(jìn)行初始化怎么做呢,可以采用如下辦法:
var array [5]int array = [5]int{1,2,3,4,5}
這兩步比較繁瑣,Go為我們提供了:=
操作符,可以讓我們在創(chuàng)建數(shù)組的時候直接初始化。
array:=[5]int{1,2,3,4,5}
這種簡短變量聲明的方式不僅適用于數(shù)組,還適用于任何數(shù)據(jù)類型,這也是Go語言中常用的方式。
有時候我們更懶,連數(shù)組的長度都不想指定。不過沒有關(guān)系,使用…代替就好了,Go會自動推導(dǎo)出數(shù)組的長度。
array:=[...]int{1,2,3,4,5}
假如我們只想給索引為 1 和 3 的數(shù)組初始化相應(yīng)的值,其他都為 0 怎么做呢,直接的辦法有:
array:=[5]int{0,1,0,4,0}
還有一種更好的辦法,上面講默認(rèn)初始化為零值,那么我們就可以利用這個特性,只初始化索引 1 和 3 的值:
array:=[5]int{1:1,3:4}
使用數(shù)組
數(shù)組的訪問非常簡單,通過索引即可,操作符為[]。因?yàn)閮?nèi)存是連續(xù)的,所以索引訪問的效率非常高。
array:=[5]int{1:1,3:4} fmt.Printf("%d",array[1])
修改數(shù)組中的一個元素也很簡單:
array:=[5]int{1:1,3:4} fmt.Printf("%d\n",array[1]) array[1] = 3 fmt.Printf("%d\n",array[1])
如果我們要循環(huán)打印數(shù)組中的所有值,一個傳統(tǒng)的就是常用的for循環(huán):
func main() { array := [5]int{1: 1, 3: 4} for i := 0; i < 5; i++ { fmt.Printf("索引:%d,值:%d\n", i, array[i]) } }
不過大部分時候,我們都是使用for rang循環(huán):
func main() { array := [5]int{1: 1, 3: 4} for i, v := range array { fmt.Printf("索引:%d,值:%d\n", i, v) } }
這兩段示例代碼,輸出的結(jié)果是一樣的。
同樣類型的數(shù)組是可以相互賦值的,不同類型的不行,會編譯錯誤。那么什么是同樣類型的數(shù)組呢?Go語言規(guī)定,必須是長度一樣,并且每個元素的類型也一樣的數(shù)組,才是同樣類型的數(shù)組。
array := [5]int{1: 1, 3: 4} var array1 [5]int = array //success var array2 [4]int = array1 //error
指針數(shù)組和數(shù)組本身差不多,只不過元素類型是指針。
array := [5]*int{1: new(int), 3:new(int)}
這樣就創(chuàng)建了一個指針數(shù)組,并且為索引 1 和 3 都創(chuàng)建了內(nèi)存空間,其他索引是指針的零值nil
,這時候我們要修改指針變量的值也很簡單,如下即可:
array := [5]*int{1: new(int), 3:new(int)} *array[1] = 1
以上需要注意的是,只可以給索引 1 和 3 賦值,因?yàn)橹挥兴鼈兎峙淞藘?nèi)存,才可以賦值。如果我們給索引 0 賦值,運(yùn)行的時候,會提示無效內(nèi)存或者是一個nil指針引用。
panic: runtime error: invalid memory address or nil pointer dereference
要解決這個問題,我們要先給索引 0 分配內(nèi)存,然后再進(jìn)行賦值修改。
array := [5]*int{1: new(int), 3:new(int)} array[0] =new(int) *array[0] = 2 fmt.Println(*array[0])
函數(shù)間傳遞數(shù)組
在函數(shù)間傳遞變量時,總是以值的方式。如果變量是個數(shù)組,那么就會整個復(fù)制,并傳遞給函數(shù)。如果數(shù)組非常大,比如長度 100 多萬,那么這對內(nèi)存是一個很大的開銷。
func main() { array := [5]int{1: 2, 3:4} modify(array) fmt.Println(array) } func modify(a [5]int){ a[1] =3 fmt.Println(a) }
通過上面的例子,可以看到,數(shù)組是復(fù)制的,原來的數(shù)組沒有修改。我們這里是 5 個長度的數(shù)組還好,如果有幾百萬怎么辦,有一種辦法是傳遞數(shù)組的指針,這樣,復(fù)制的大小只是一個數(shù)組類型的指針大小。
func main() { array := [5]int{1: 2, 3:4} modify(&array) fmt.Println(array) } func modify(a *[5]int){ a[1] =3 fmt.Println(*a) }
這是傳遞數(shù)組的指針的例子,會發(fā)現(xiàn)數(shù)組被修改了。所以這種情況雖然節(jié)省了復(fù)制的內(nèi)存,但是要謹(jǐn)慎使用,因?yàn)橐徊恍⌒?,就會修改原?shù)組,導(dǎo)致不必要的問題。
這里注意,數(shù)組的指針和指針數(shù)組是兩個概念,數(shù)組的指針是*[5]int
,指針數(shù)組是[5]*int
,注意*
的位置。
針對函數(shù)間傳遞數(shù)組的問題,比如復(fù)制問題,比如大小僵化問題,都有更好的解決辦法,這個就是切片,它更靈活
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
網(wǎng)頁名稱:Go語言之?dāng)?shù)組-創(chuàng)新互聯(lián)
分享鏈接:http://jinyejixie.com/article40/dejgho.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、云服務(wù)器、網(wǎng)頁設(shè)計公司、標(biāo)簽優(yōu)化、手機(jī)網(wǎng)站建設(shè)、網(wǎng)站設(shè)計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)