原文:http://golang.org
翻譯:劉金雨/劉雲濤 <yuntao.liu#gmail.com> http://www.log4think.com
資料類型 Types
Go有一些常見的資料類型,例如 int 和 float,其值採用機器“適用”的大小來表示。也有定義了明確大小的資料類型,例如 int8、float64 等,以及不帶正負號的整數類型,例如 uint、uint32 等。這些都是完全不同的資料類型,即使 int 和int32 都是32位整數,但它們是不同的類型。對於表示字串元素的類型 byte 和uint8 也是同樣如此。
說到字串( string ),這也是一個內建的資料類型。 字串的值不僅僅是一個byte 的數組,它的值是不可改變的。一旦確定了一個字串的值,就不能再修改了。但一個字串變數的值可以通過重新賦值來改變。下面這段來自 strings.go的代碼是合法的:
11 s := "hello";
12 if s[1] != 'e' { os.Exit(1) }
13 s = "good bye";
14 var p *string = &s;
15 *p = "ciao";
然而下面這段代碼是非法的,因為它試圖修改一個字串的值:
s[0] = 'x';
(*p)[1] = 'y';
按照C++的說法,Go的字串有點類似帶了 const 修飾符,指向字串的指標也類似於一個 const 字串的引用(reference).
沒錯,前面看到的那些是指標,然而Go語言中的指標在用法方面有所簡化,後文會提到。
數組的聲明如下所示:
var arrayOfInt [10]int;
數組同字串一樣是“值”,但是卻是可變的。與C不同的是,C語言中 arrayOfInt可以當做一個指向int的指標來用。在Go中,因為數組是“值”,因此 arrayOfInt被看做(也被用做)指向數組的指標。
數組的大小是其資料類型的一部分。但是,你可以聲明一個 slice 變數,然後可以用一個指向具有相同元素類型的數組指標給它賦值,更常見的是用一個形式為a[low : high]的 slice 運算式,該運算式表示下標從 low 到 high-1 的子數組。 Slice 類型類似數組,但沒有顯式指定大小 ([] 之於 [10]),用於表示一個隱性(通常是匿名的)數組。如果不同的 slice 都是表示同一個數組中的資料,它們可以共用該數組的記憶體,但不同的數組則永遠不會共用記憶體資料。
Slice 在Go 程式中比數組更常見。它更靈活,並且具有引用的語義,效率也更高。其不足之處在於無法像數組一樣精確控制儲存方式,如果想在一個資料結構中儲存一個具有100個元素的序列,應該採用數組。
當給函數傳一個數組參數的時候,絕大多數情況下都會把參數聲明為 slice 類型。當調用函數時,先取數組地址,然後Go會建立一個 slice 的引用,然後傳這個引用過去。
可以用 slice 來寫這個函數(來自 sum.go):
09 func sum(a []int) int { // 返回一個整數
10 s := 0;
11 for i := 0; i < len(a); i++ {
12 s += a[i]
13 }
14 return s
15 }
之後這樣來調用:
19 s := sum(&[3]int{1,2,3}); // a slice of the array is passed to sum
注意在sum()的參數列表後面加 int 定義了其傳回值類型(int)。[3]int{1,2,3} 的形式是一個資料類型後面接一個大括弧括起來的運算式,整個這個運算式構造出了一個值,這裡是一個包含三個整數的數組。前面的 & 表示提取這個值的地址。這個地址會被隱性的轉為一個 slice 傳給 sum() 。
如果想建立一個數組,但希望編譯器來幫你確定數組的大小,可以用 ... 作為數組大小:
s := sum(&[...]int{1,2,3});
實際使用中,除非非常在意資料結構的儲存方式,否則 slice 本身 (用[]且不帶&) 就足夠了:
s := sum([]int{1,2,3});
除此之外還有map,可以這樣初始化:
m := map[string]int{"one":1 , "two":2}
sum還第一次出現了內建函數 len(),用於返回元素數量。可以用於字串、數組、slice、map、map 和 channel.
此外, for 迴圈中的 range 也可以用於字串、數組、slice、map、map 和 channel。例如
for i := 0; i < len(a); i++ { ... }
遍曆一個序列的每個元素,可以寫成
for i, v := range a { ... }
其中, i 會賦值為下標, v 會賦值為 a 中對應的值,Effective Go 中包含了更多的用法示範。