枚舉
枚舉指一系列的相關的常量,比如下面關於一個星期的中每天的定義,通過上篇博文,我們可以用在const后跟一對圓括號的方式定義一組常量,這種定義法在go語言中通常用於定義枚舉值。go語言並不支持眾多其他語言明確支持的enum關鍵字。
下面是一個常規的枚舉表示法,其中定義了一系列整型常量。
const ( Sunday = iota Monday Tuesday Wednesday Thursday Friday Saturday numberOfDays // 這個常量沒有導出 )
同go語言中的其他符號(symbol)一樣,以大寫字母開頭的常量在包外可見。
以上列子中 numberOfDays為包內私有,其他符號則可被其他包訪問。
數據基本類型
布爾類型: bool 整數類型: int8、byte、int6、int、uint、uintptr等。 浮點類型: float32、float64。 復數類型:complex64、complex128。 字符串:string。 字符類型:rune。 錯誤類型:error。 處上之外,go語言還支持一下的復合類型。 指針(pointer) 數組(array) 切片(slice) 字典(map) 通道(chan) 結構體(struct) 接口(interface)
上述類型的特點在於使用方便,但使用者不能對這些類型的長度做任何假設。對於常規的開發來說,用int和uint就可以了,沒必要用int8之類明確指定長度的類型 ,以免導致移植困難。
布爾類型
go語言中的布爾類型與其他語言基本一致,關鍵字也是 bool ,可賦值為預定義的true和false。
var test bool test = true test_two := (1 == 2) // test_two也會被推導為bool類型 PS: 布爾類型不能接受其他類型賦值,不支持自動或強制的類型轉換。 下面一些錯誤的語法: var a bool a = 1 // 語法錯誤 a = bool(1) // 語法錯誤 以下的用法才是正確: var one bool one = (1 != 0) // 正確語法 fmt.Println("result:", one) // go的輸出 Println 輸出結果: result : true
整型:
整型是所有語言里最基礎的類型了。
類型 長度 值范圍 int8 1 -128 ~ 127 uint8(既byte) 1 0 ~255 int16 2 -32 768 ~ 32 767 uint16 2 0~65 535 int32 4 -2 147 483 648 ~ 2 147 483 647 uint32 4 0 ~ 4 294 967 295 int64 8 -9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807 uint64 8 0 ~ 18 446 744 073 709 551 615 int 因平台而定 因平台而定 uint 因平台而定 因平台而定 uintptr 同指針 在32位平台下為4字節,64位平台下為8字節
①、類型表示
需要注意的是,int和int32在go語言里被認為是兩種不同的類型,編譯器也不會幫你自動做轉換類型,比如以下的列子會有編譯錯誤:
var value2 int32 value1 := 64 // value1將會被自動推導為int類型 value2 = value1 // 編譯錯誤 編譯錯誤類似於: cannot use valu1 (type int) as type int32 in assignment。 使用強制類型轉換可以解決這個編譯錯誤: value2 = int32 (value1) //編譯通過
當然,開發者在做強制類型轉換時,需要注意數據長度被截斷而發生的數據精度損失(比如將浮點數強制轉為整數)和值溢出(值超過轉換的目標類型的值范圍時)問題。
②、數值運算
go語言支持下面的常規整數運算: +、-、*、/、和%。加減乘除就不解釋了,需要說下的是,%和C語言中一樣是求余運算,比如:
5 % 3 // 結果: 2
③、比較運算
go語言支持以下的幾種比較運算符: > 、 < 、 ==、>=、 <=和!=。這一點與其他大多數的語言相通,與C語言完全一致。
④、運算符
運算 含義 樣 列 x << y 左移 124 << 2 // 結果為496 x >> y 右移 124 >> 2 // 結果為31 x ^ y 異或 124 ^ 2 // 結果為126 x & y 與 124 & 2 // 結果為0 x | y 或 124 | 2 // 結果為126 ^x 取反 ^2 // 結果為3
go語言的大多數位運算符與C語言都比較類似,除了取反在C語言中是~x,而在go語言中是^x。
浮點型
浮點型用於表示包含小數點的數據,比如1.234就是一個浮點型數據,在go語言中的浮點類型采用IEEE-754標准的表達方式。
①、浮點數表示
go語言定義了兩個類型float32和float64,其中float32等價於C語言的float類型,float64等價於C語言的double類型。
在go語言中,定義一個浮點數變量的代碼如下:
var fvalue1 float32 fvalue1 = 12 fvalue2 := 12.0 // 如果不加小數點,fvalue2會被推導為整型而不是浮點型
對於以上列子類型被自動推導的fvalue2,需要注意的是其類型將被自動設為float64,而不管賦給它的數字是否使用32位長度表示的,因此,對於以上列子,下面的賦值將導致編譯錯誤:
fvalue1 = fvalue2 而必須使用這樣的強制類型轉換: fvalue1 = float32(fvalue2)
②、浮點數比較
因為浮點數不是一種精確的表達方式,所以像整型那樣直接用==來判斷兩個浮點數是否相等是不可行的,這可能會導致 不穩定的結果 。
下面是一種推薦的替代方案。import "mat// p為用戶自定義的比較精度, 比如:0.00001
func IsEqual(f1, f2, p float64) bool { return math.Fdim(f1, f2) < p }
復數類型
復數實際上由兩個實數(在計算機中用浮點數表示)構成,一個表示 實部(real),一個表示虛部(imag),如果了解了數學上的復數是怎么回事,那么go語言的復數就非常容易理解了。
①、復數表示
復數示例:
var value1 complex64 // 由2個float32構成復數類型 value1 = 3.2 + 12i value2 := 3.2 + 12i //value2是complex128類型 value3 := complex(3.2, 12) //value3結果同value2
②、實部與虛部
對於一個復數z = complex(x, y),就可以通過go語言內置函數real(z)獲得該復數的實部,也就是x,通過imag(z)獲得該復數的虛部,也就是y。
字符串
在go語言中,字符串也是一種基本類型,相比之下,C/C++語言中並不存在原生的字符串類型,通常使用字符數組來表示,並以字符指針來傳遞。
go語言中一下是字符串的聲明和初始化。
var str string // 聲明一個字符串變量 str = "Hello world" // 字符串賦值 ch := str[0] // 取字符串的第一個字符 fmt.Printf("The length of \"%s\" is %d \n", str, len(str)) fmt.Printf("The first character of \" %s\"is %c.\n", str, ch) 輸出結果: The length of "Hello world" is 11 The first character of "Helllo world" is H.
字符串的內容看可以用類似於數組下標的方式獲取,但與數組不同,字符串的內容不能再初始化后被修改,比如一下列子:
str := "Hello world" // 字符串也支持聲明時進行初始化的做法 str[0] = "x" // 編譯錯誤 編譯器會報類似如下錯誤: cannot assign to str[0]
字符串的操作
運算 含義 樣列 x + y 字符串連接 "Hello" + "123" // hello123 len(str) 字符串長度 len("hello") // 5 s[*] 取字符 "hello" [1] // e 更多方法請參考string標准庫包!!!
①字符串遍歷
go語言中支持兩種遍歷方式,一種是以字節數組的方式遍歷:
str := "Hello,世界" n := len(str) for i := 0; i < n; i++ { ch := str[i] // 依據下標取字符串中的字符,類型為byte fmt.Println(i, ch) } 結果: 0 72 1 101 2 108 3 108 4 111 5 44 6 32 7 228 8 184 9 150 10 231 11 149 12 140
可以看出,這個字符串長度為13,盡管從直觀上來說,這個字符串應該只有9個字符,這是因為每個中文字符在UTF-8中占三個字節,而不是壹個字節。
另一種是以Unicode字符遍歷:
str := "Hello, 世界" for i, ch := range str { fmt.Println(i, ch) // ch的類型為true } 結果: 0 72 1 101 2 108 3 108 4 111 5 44 6 32 7 19990 10 30028
以Unicode字符方式遍歷時,每個字符的類型是rune(早期的go語言用int類型表示Unicode字符),而不是byte。
字符類型
在go語言中支持兩個字符類型,一個是byte(實際上是uint8的別名),代表UTF-8字符串的單個字節的值,另一個是rune,代表單個Unicode字符。