深入學習golang(1)—陣列與切片

YY哥發表於2014-09-30

資料(array)與切片(slice)

陣列宣告:

ArrayType   = "[" ArrayLength "]" ElementType .

例如:

var a [32] int

var b [3][5] int

 

在Go和C中,陣列的工作方式有幾個重要的差別。在Go中,

(1)陣列是值型別。將一個陣列賦值給另一個,會拷貝所有的元素。

(2) 如果你給函式傳遞一個陣列,其將收到一個陣列的拷貝,而不是它的指標。

(3)陣列的大小是其型別的一部分,型別[10]int和[20]int是不同的。陣列長度在宣告後,就不可更改。

 

切片宣告:

SliceType = "[" "]" ElementType .

例如:

var a []int

沒有初始化的slice為nil。

 

切片(slice)對陣列進行封裝,實際上,切片可以看成大小可以動態變化的陣列,這一點類似C++中std::vector。就像std::vector在實際C++程式設計中大量使用一樣,Go中大多數的陣列程式設計都是通過切片完成,而不是簡單陣列。

 

一般來說,有兩種方式來初始化切片:

(1)通過陣列

var myArray [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

var mySlice []int = myArray[:5]

 

(2)通過make

語法:

make([]T, length, capacity)

 

建立一個初始長度為5,容量為10為切片,切片的每個元素都為0:

slice1 := make([]int, 5, 10)

 

建立一個長度為5的切片,並初始化切片的每個元素:

slice2 := []int{1, 2, 3, 4, 5}

 

對於切片,最重要的特點就是長度是可變的:

slice2 := []int{1, 2, 3, 4, 5}

fmt.Println("slice:", slice2)

 

slice2 = append(slice2, 6)

fmt.Println("slice:", slice2)

 

輸出:

slice: [1 2 3 4 5]

slice: [1 2 3 4 5 6]

 

函式append是GO專門為切片增加元素而提供的一個內建函式。

 

切片持有對底層陣列的引用,如果你將一個切片賦值給另一個,二者都將引用同一個陣列。如果函式接受一個切片作為引數,那麼其對切片的元素所做的改動,對於呼叫者是可見的,好比是傳遞了一個底層陣列的指標。

 

func (f *File) Read(b []byte) (n int, err error)

這個os.File的Read方法,它接受一個切片引數,切片中的長度已經設定了要讀取的資料的上限。對於C/C++,需要同時提供一個緩衝區的指標,和緩衝區的大小:

int read(File* f, char* buf, int len)

從這裡可以看到,GO的寫法要簡單一些。


 

切片(陣列)的遍歷

 

在go語言中,遍歷切片或者陣列,有兩種方式:

 

傳統方式:

 

for i := 0; i <len(mySlice); i++ {

fmt.Println("mySlice[", i, "] =", mySlice[i])

}

 

 

 

使用range表示式

 

range表示式有兩個返回值,第一個是索引,第二個是元素的值:

 

for i, v := range mySlice {

fmt.Println("mySlice[", i, "] =", v)

}

 

使用range讓程式碼更加簡潔,所以在go程式設計中也更加常用。



作者:YY哥 
出處:http://www.cnblogs.com/hustcat/ 
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。

相關文章