GoLang 陣列與切片

2021-10-07 07:31:21 字數 4585 閱讀 3568

陣列是具有相同唯一型別的一組已編號長度固定的資料項序列(這是一種同構的資料結構);這種型別可以是任意的原始型別例如整型、字串或者自定義型別。

陣列長度必須是乙個常量表示式,並且必須是乙個非負整數

陣列長度也是陣列型別的一部分,所以[5]int[10]int是屬於不同型別的。

一維陣列宣告以及初始化常見方式如下:

var arrage  = [5]int

var arrname = [5]string //指定索引位置初始化

// var arrcount = [4]int //指定索引位置初始化

var arrlazy = [...]int //陣列長度初始化時根據元素多少確定

var arrpack = [...]int //指定索引位置初始化,陣列長度與此有關

var arrroom [20]int

var arrbed = new([20]int)

陣列在宣告時需要確定長度,但是也可以採用上面不定長陣列的方式宣告,在初始化時會自動確定好陣列的長度。上面arrpack宣告中len(arrpack)結果為6,表明初始化時已經確定了陣列長度。而arrroomarrbed這兩個陣列的所有元素這時都為0,這是因為每個元素是乙個整型值,當宣告陣列時所有的元素都會被自動初始化為預設值0

go 語言中的陣列是一種值型別(不像 c/c++ 中是指向首元素的指標),所以可以通過new()來建立:

var arr1 = new([5]int)
那麼這種方式和var arr2 [5]int的區別是什麼呢?arr1的型別是*[5]int,而arr2的型別是[5]int。在go語言中,陣列的長度都算在型別裡。

package main

import "fmt"

func main()

輸出結果:

100 100

100 0

從上面**結果可以看到,new([5]int)建立的是陣列指標,arr其實和arr1指向同一位址,故而修改arr1arr同樣也生效。而newarr是由arr2值傳遞(拷貝),故而修改任何乙個都不會改變另乙個的值。在寫函式或方法時,如果引數是陣列,需要注意引數長度不能過大。

由於把乙個大陣列傳遞給函式會消耗很多記憶體(值傳遞),在實際中我們通常有兩種方法可以避免這種現象:

通常使用切片是第一選擇。

多維陣列在go語言中也是支援的,例如:

[...][5]int,  }  // len() 長度根據實際初始化時資料的長度來定,這裡為2

[3][5]int // len() 長度為3

[2][2][2]float64 // 可以這樣理解 [2]([2]([2]float64))

在定義多維陣列時,僅第一維允許使用,而內建函式lencap也都返回第一維度長度。定義陣列時使用表示長度,表示初始化時的實際長度來確定陣列的長度。

b := [...][5]int,  }

fmt.println(b[1][3], len(b)) //60 2

陣列元素可以通過索引(下標)來讀取(或者修改),索引從 0 開始,第乙個元素索引為 0,第二個索引為 1,以此類推。(陣列以 0 開始在所有類 c 語言中是相似的)。元素的數目,也稱為長度或者陣列大小必須是固定的並且在宣告該陣列時就給出(編譯時需要知道陣列長度以便分配記憶體);陣列大小最大為 2 gb。

遍歷陣列的方法既可以for條件迴圈,也可以使用for-range。這兩種for結構對於切片(slices)來說也同樣適用。

另外,如陣列元素型別支援==!=操作符,那麼陣列也支援此操作,但如果陣列型別不一樣則不支援(需要長度和資料型別一致,否則編譯不通過)。

切片(slice是對底層陣列乙個連續片段的引用,所以切片是乙個引用型別。切片提供對該陣列中編號的元素序列的訪問。未初始化切片的值為nil

與陣列一樣,切片是可索引的並且具有長度。切片s的長度可以通過內建函式len()獲取;與陣列不同,切片的長度可能在執行期間發生變化。元素可以通過整數索引0len(s)-1來定址。我們可以把切片看成是乙個長度可變的陣列。

切片提供了計算容量的函式cap(),可以測量切片最大長度。切片的長度永遠不會超過它的容量,所以對於切片s來說,這個不等式永遠成立:0 <= len(s) <= cap(s)

多個切片如果表示同乙個陣列的片段,它們可以共享資料;因此乙個切片和相關陣列的其他切片是共享儲存的,相反,不同的陣列總是代表不同的儲存。陣列實際上是切片的構建塊。

切片可以延伸超過切片的末端,容量是切片長度與切片之外的陣列長度的總和。

使用內建函式make()可以給切片初始化,該函式指定切片型別和指定長度和可選容量的引數。

注意絕對不要用指標指向slice。切片本身已經是乙個引用型別,所以它本身就是乙個指標!!

切片初始化:

var slice1 type = arr1[start:end]

var x = int

當相關陣列還沒有定義時,我們可以使用make()函式來建立乙個切片 同時建立好相關陣列

slice1 := make(type, len)

slice1 := make(type, len, cap)

如果從陣列或者切片中生成乙個新的切片,我們可以使用下面的表示式:

a[low : high : max]
max-low的結果表示容量,high-low的結果表示長度。

通過改變切片長度得到新切片的過程稱之為切片重組 (reslicing)

slice1 := make(type, start_length, capacity)
當我們在乙個切片基礎上重新劃分乙個切片時,新的切片會繼續引用原有切片的陣列。如果你忘了這個行為的話,在你的應用分配大量臨時的切片用於建立新的切片來引用原有資料的一小部分時,會導致難以預期的記憶體使用。

簡單說,有乙個切片長度和容量都是10000,你現在卻只需要使用其中的三個元素,如下所示:

package main

import "fmt"

func get() byte

func main()

上面的**原因很簡單,對切片進行切片,由於切片是引用型別,所以如果你原切片占用空間很多,而現在只需要一點點的資料,那麼最好不要用切片,而應該用copy函式,將少部分的資料複製出來,這樣就可以釋放原切片空間。

func get() byte
s0 := int

有乙個奇特之處,對乙個切片s=int

package main

import "fmt"

func main()

p := s[1:]

q := s[:4]

fmt.println(len(p), cap(p)) // 4 4

fmt.println(len(q), cap(q)) // 4 5

}

golang陣列,切片

陣列 同一種資料型別的固定長度序列 陣列的定義 var a len int 比如 var a 5 int 長度是陣列型別的一部分,因此,var a 5 int 和 var a 10 int 是不同的型別 陣列的初始化 func chushi var age1 5 int var age2 int v...

golang 陣列和切片

陣列和切片的建立func main output 1 0 ps 陣列宣告時,所有元素預設值都是0。一般很少這樣做,盡量自己初始化。func main output panic runtime error index out of range goroutine 1 running main.main...

Golang 之陣列 切片

陣列在使用前必須宣告長度,在golang中,陣列屬於值型別,在函式傳遞中,實際傳遞的是陣列的拷貝並不是陣列指標拷貝 是一種引用型別,它是不定長的,指向底層陣列 slice底層結構 type sliceheader struct 1.如果切片的容量小於1024個元素,那麼擴容的時候slice的cap就...