目錄陣列是具有相同唯一型別的一組已編號且長度固定的資料項序列(這是一種同構的資料結構);這種型別可以是任意的原始型別例如整形、字串或者自定義型別(結構體、介面)。陣列長度必須是乙個常量表示式,並且必須是乙個非負整數,陣列下標是從0開始的,並且陣列的長度是固定不可變的,陣列中元素的位址是連續的。陣列長度也是陣列型別的一部分,所以[5]int和[10]int是屬於不同型別的。
在其它程式語言中,陣列一般都是引用型別,而在go語言中,陣列屬於值型別。
注意:如果我們想讓陣列元素型別為任意型別的話可以使用空介面作為型別。當使用值時我們必須先做乙個型別判斷。
go語言陣列宣告需要指定元素型別及元素個數,語法格式如下:
// 變數名 [大小]型別
var variable_name [len]variable_type
示例:
定義乙個長度為5的陣列arr
var arr [5]int
以上我們宣告了乙個陣列arr
,但是我們還沒有對他進行初始化,但是宣告的變數都會有預設值,int型別的變數預設值是0,所以arr陣列中的每個元素的值都是0。
go語言中的陣列是一種值型別,所以可以通過 new() 來建立:var arr1 = new([5]int)
。那麼這種方式和var arr2 [5]int
的區別是什麼呢?arr1 的型別是*[5]int
,而 arr2的型別是[5]int
。
假如我們宣告乙個長度為5的陣列var arr [5]int
,我們來看看這個陣列在記憶體中的結構是怎麼樣的。
上圖就是乙個go語言陣列在記憶體的結構,在這個arr陣列中,由於我們宣告的是int32型別,所以陣列中的每個元素在記憶體中占用的位元組數是32/8=4位元組,通過arr陣列每個元素16進製制位址我們可以發現,陣列中後乙個元素的位址比前乙個元素的位址大4個位元組,這個4位元組正好是int32型別元素占用的記憶體大小,由此我們也能得出結論:陣列中元素的記憶體位址是連續的;當宣告陣列時所有的元素都會被自動初始化為陣列型別的預設值(int型別的預設值是0,所以arr中每個元素的預設值都是0);陣列的下標識從0開始的。陣列arr的位址就是陣列第乙個元素(下標為0的元素)的位址,通過下圖列印arr的位址和arr[0]的位址就可以證明
剛剛宣告的陣列已經被預設的元素型別零值初始化了,如果我們再次進行初始化怎麼做呢,可以採用如下辦法:
var arr [5]int
arr = [5]int
go語言提供了宣告加初始化的:=
操作符,以讓我們在建立陣列的時候直接初始化。
arr := [5]int
這種簡短變數宣告的方式不僅適用於陣列,還適用於任何資料型別,這也是go語言中常用的方式。
我們也可以在定義陣列是不明確指定長度,讓編譯器自動推導出長度,可以使用...
來替代具體的長度
arr := [...]int
如果我們只想給陣列的部分元素指定值,其他元素採用預設值我們可以採用下面的辦法
arr := [5]int
這種方式表示我們只給陣列下標為0的元素賦值為3,下標為4的元素賦值為6,其它元素的值依然是該型別的預設值(int的預設值是0)。
陣列元素的訪問非常簡單,通過索引(下標)即可訪問陣列的元素。
arr := [5]int
fmt.println(arr[0], arr[1], arr[2], arr[3], arr[4])
修改陣列的某個元素也很簡單:
arr := [5]int
fmt.println(arr[0])
arr[0] = 66
fmt.println(arr[0])
如果我們要迴圈列印陣列中的所有值,乙個傳統的就是常用的for迴圈:
for i := 0; i < len(arr); i++
不過大部分時候,我們都是使用for rang迴圈:
for i, v := range arr
同樣型別的陣列是可以相互賦值的,不同型別的不行,會編譯錯誤。那麼什麼是同樣型別的陣列呢?go語言規定,必須是長度一樣,並且每個元素的型別也一樣的陣列,才是同樣型別的陣列。
arr := [5]int
var arr2 [5]int = arr //可以
var arr3 [3]int = arr //不可以
指標陣列和陣列本身差不多,只不過元素型別是指標。
arr := [5]*int
這樣就建立了乙個指標陣列,並且為索引1和3都建立了記憶體空間,其他索引是指標的零值nil
,這時候我們要修改指標變數的值也很簡單,如下即可:
array := [5]*int
*array[1] = 1
以上需要注意的是,只可以給索引1和3賦值,因為只有它們分配了記憶體,才可以賦值,如果我們給索引0賦值,執行的時候,會提示無效記憶體或者是乙個nil指標引用。
panic: runtime error: invalid memory address or nil pointer dereference
要解決這個問題,我們要先給索引0分配記憶體,然後再進行賦值修改。
arr := [5]*int
arr[0] =new(int)
*arr[0] = 2
fmt.println(*arr[0])
在go中,陣列也是值型別,所以在函式間傳遞變數時,麼就會整個複製,並傳遞給函式,如果陣列非常大,比如長度100多萬,那麼這對記憶體是乙個很大的開銷。
func main() //[0 2 0 4 0]
modify(array)
fmt.println(array) //[0 2 0 4 0]
}func modify(a [5]int)
通過上面的例子,可以看到,陣列是複製的,原來的陣列沒有修改。我們這裡是5個長度的陣列還好,如果有幾百萬怎麼辦,有一種辦法是傳遞陣列的指標,這樣,複製的大小只是乙個陣列型別的指標大小。
func main() //[0 2 0 4 0]
modify(&array)
fmt.println(array) //[0 333 0 4 0]
}func modify(a *[5]int)
這裡注意,陣列的指標和指標陣列是兩個概念,陣列的指標是陣列是多個相同型別資料的組合,乙個陣列一旦宣告/定義了,其長度是固定的,不能動態變化。*[5]int
,指標陣列是[5]*int
,注意*
的位置。
陣列中的元素可以是任何資料型別,包括值型別和引用型別,但是不能混用。
陣列建立後,如果沒有賦值,有預設值
數值型別陣列:預設值為0
字串型別陣列:預設值為""
bool陣列: 預設值為false
指標陣列: 預設值nil
使用陣列的步驟:1.宣告陣列並開闢空間2.給陣列各個元素賦值3.使用陣列
陣列的下標從0開始
陣列下標必須在指定範圍內使用,否則報panic:陣列越界
go的陣列屬於值型別,在預設情況下是值傳遞,因此會進行值拷貝。陣列間不會相互影響
如果想在其它函式中,去修改原來的陣列,可以使用引用傳遞(指標方式)
長度是陣列型別的一部分,在傳遞函式引數時,需要考慮陣列的長度
Go語言 陣列
定義陣列的長度和型別,預設使用型別的零值進行初始化 var a1 10 int 不指定陣列的長度,指定型別,缺省會使用初始值設定陣列的長度 初始值有幾個,陣列長度就是幾 var a2 int 指定陣列的長度和型別,同時初始化全部或者部分的數字,元素會從前到後順序初始化 初始化時物件的數量不能大於陣列...
GO語言 陣列
陣列是同一種資料型別元素的集合。在go語言中,陣列從宣告時就確定,使用時可以修改陣列成員,但是陣列大小不可變化。基本語法 定義乙個長度為3元素型別為int的陣列a var a 3 intvar 陣列變數名 元素數量 t比如 var a 5 int,陣列的長度必須是常量,並且長度是陣列型別的一部分。一...
go語言 陣列
陣列是同一種資料型別元素的集合。在go語言中,陣列從宣告時就確定,使用時可以修改陣列成員,但是陣列大小不可變化。基本語法 定義乙個長度為3元素型別為int的陣列a var a 3 intvar 陣列變數名 元素數量 t比如 var a 5 int,陣列的長度必須是常量,並且長度是陣列型別的一部分。一...