這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
今天來說一下go裡面的array。要對go中的array進行瞭解,就需要知道go中的另外一個概念slice,而要知道slice你又要知道new和make的區別,而要知道new和make的區別你又得瞭解value,pointer,reference的區別。下面我們來逐一看一下這些概念。
1、value, pointer以及reference
這些概念其實與其他語言是一樣的,但是我們在這裡單獨提出來說這個是因為在go語言裡都是使用value的,因此如果將一個array賦值給另外一個array,必然會涉及到值拷貝,比如 a := [9]int{0,1,2,3,4,5,6,7,8} b := a,那麼這裡b就拷貝到了a的值。而相反,對於pointer和reference而言則不會有這樣的拷貝
2、new和make
在go語言裡new和其他語言一樣,分配一個類型執行個體的空間,初始化為0並返回這個地址。而make則只是針對array,map以及channel類型的,因為這些類型需要初始化否則無法使用,或者說的直白一點,這些類型並不屬於基礎資料型別 (Elementary Data Type)的範疇,你在聲明一個int類型時,go會為你分配一個int類型所需要的空間,但是如果你聲明一個[]int,它就不能分配了,因為它不知道要分配多少空間。make的作用就是分配空間,並且返回這個空間的引用。注意這裡是引用而不是指標。
3、slice和array
對於go來說,數組的大小是和數組定義的一部分,[6]int和[5]int是不同的資料類型,這樣一來就很明顯了,我們需要一個統一的表示數組的方式,於是slice就出現了,slice的定義很簡單[]int就表示slice,是的,不要驚訝,所謂slice就是不指定數組大小的數組[]interface。那麼如何得到一個slice呢?有兩種方法,一個是make,比如make(int, 10, 100)表示產生一個int類型的數組,它的大小是100,但是目前只使用10個。或者a [6]int; a[0:5];這樣也可以得到一個slice。
多維陣列在go裡的表現不像c語言那樣是和一維數組相通的,而是像java那樣,需要一維一維往下。
比如a [9][9]int,其實代表有一個數組a它有9個元素,其中每個元素都是[9]int類型的而已。
之前在郵件裡的討論裡看到過有人提議說這種表示方式對於多維陣列來說太繁瑣了,但是後來的討論表明,如果要支援slice的話,多維的實現會使整個語言的複雜度變得很大,因此沒有必要去專門實現一個這樣的東西。