Go 語言是一種靜態類型的編程語言。這意味著,編譯器需要在編譯時知曉程式里每個值的類型。數據類型的出現是為了把數據分成所需記憶體大小不同的數據,編程的時候需要用大數據的時候才需要申請大記憶體,就可以充分利用記憶體。 Go語言內置以下這些基礎類型: 布爾類型:bool 整型:int8、byte、int16、 ...
Go 語言是一種靜態類型的編程語言。這意味著,編譯器需要在編譯時知曉程式里每個值的類型。數據類型的出現是為了把數據分成所需記憶體大小不同的數據,編程的時候需要用大數據的時候才需要申請大記憶體,就可以充分利用記憶體。
- Go語言內置以下這些基礎類型:
- 布爾類型:bool
- 整型:int8、byte、int16、int、uint、uintptr等
- 浮點類型:float32、float64。
- 複數類型:complex64、complex128
- 字元串:string
- 字元類型:rune
- 錯誤類型:error
此外,Go語言也支持以下這些複合類型:
- 指針:pointer
- 數組:array
- 切片:slice
- 字典:map
- 通道:chan
- 結構體:struct
- 介面:interface
1、類型
1.1、布爾類型
布爾型的值只可以是常量 true 或者 false。例如:
var b bool = true
1.2、整型
序號 | 長度(位元組) | 類型與描述 |
---|---|---|
1 | 1 | uint8:無符號 8 位整型 (0 到 255) |
2 | 2 | uint16:無符號 16 位整型 (0 到 65535) |
3 | 4 | uint32:無符號 32 位整型 (0 到 4294967295) |
4 | 8 | uint64:無符號 64 位整型 (0 到 18446744073709551615) |
5 | 1 | int8:有符號 8 位整型 (-128 到 127) |
6 | 2 | int16:有符號 16 位整型 (-32768 到 32767) |
7 | 4 | int32:有符號 32 位整型 (-2147483648 到 2147483647) |
8 | 8 | int64:有符號 64 位整型 (-9223372036854775808 到 9223372036854775807) |
9 | 1 | byte:類似 uint8 |
10 | 4 | rune:類似 int32 |
11 | 平臺相關 | uint:無符號的整型,32 或 64 位, |
12 | 平臺相關 | int:有符號的整型,32 或 64 位,在Go語言中,int與int32是不同的數據類型, 編譯器不會自動做數據轉換 |
13 | 同指針 | uintptr:無符號整型,用於存放一個指針,在32位平臺下為4位元組,64位平臺下為8位元組 |
例:
var value int32 value := 64 // value將會被自動推導為int類型
對整型數據可以進行數值運算、比較運算、位運算,詳細在“運算符”這一節說明。
1.3、浮點型
浮點型用於表示包含小數點的數據,比如1.234就是一個浮點型數據。Go語言中的浮點類型採用IEEE-754標準的表達方式。
序號 | 長度(位元組) | 類型與描述 |
---|---|---|
1 | 4 | float32:單精度 |
2 | 8 | float64:雙精度 |
示例:
var fvalue1 float32 fvalue1 = 12 fvalue2 := 12.0 // 如果不加小數點,fvalue2會被推導為整型而不是浮點型
1.4、複數型
這裡就是我們數學中的複數,實際上由兩個實數(在電腦中用浮點數表示)構成,一個表示實部(real),一個表示虛部(imag)。
示例:
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。更多關於複數的函數,請查閱math/cmplx標準庫的文檔。
1.5、字元串
在Go語言中,字元串也是一種基本類型。一個字元串是一個不可改變的位元組序列,字元串可以包含任意的數據,但是通常是用來包含可讀的文本。
1.5.1、字元串定義
var str string // 聲明一個字元串變數 str = "Hello world" // 字元串賦值
字元串中可以使用轉義字元來實現換行、縮進等效果,常用的轉義字元包括:
- \n 換行符
- \r 回車符
- \t tab 鍵
- \u 或 \U Unicode 字元
- \\ 反斜杠自身
示例:
package main import ( "fmt" ) func main() { var str = "Hello\nworld" fmt.Println(str) }
運行結果:
Hello world
多行字元串賦值
package main import ( "fmt" ) func main() { var str = `第一行 第二行 第三行\r\n 第四行` fmt.Println(str) }
運行結果
第一行 第二行 第三行\r\n 第四行
可以看出,在這種方式下,所有的轉義字元均無效,文本將會原樣輸出。註意 ` 不是單引號,是反引號即鍵盤上 1 鍵左邊的鍵。多行字元串一般用於內嵌源碼和內嵌數據等。
1.5.2、字元串編碼
Go語言中字元串的內部實現使用 UTF-8 編碼,UTF-8 是一種被廣泛使用的編碼格式,是文本文件的標準編碼,通過 rune 類型,可以方便地對每個 UTF-8 字元進行訪問。當然,Go語言也支持按照傳統的 ASCII 碼方式逐字元進行訪問。
1.5.3、字元串操作
運算 | 含義 | 示例 |
---|---|---|
+ | 字元串連接 | "Hello" + "World" // 結果為HelloWorld |
Len() | 字元串長度 | len("HelloWorld") // 結果為10 |
[] | 取字元 | "HelloWorld" [1] // 結果為'e' |
1.5.4、字元串遍歷
GO語言有兩種遍歷方法,一種是以位元組數組的方式遍歷:
package main import "fmt" func main() { str := "Hello World,你好世界" 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 32 6 87 7 111 8 114 9 108 10 100 11 44 12 228 13 189 14 160 15 229 16 165 17 189 18 228 19 184 20 150 21 231 22 149 23 140
在GO語言中漢字預設是UTF8編碼占3個位元組,字母和半形標點是ASCII編碼占1個位元組,所以len(str) == 24 ,輸出的結果也是24行。
另一種是以Unicode字元遍歷:
package main import "fmt" func main() { str := "Hello World,你好世界" for i, ch := range str { fmt.Println(i, ch) //ch的類型為rune } }
運行結果
0 72 1 101 2 108 3 108 4 111 5 32 6 87 7 111 8 114 9 108 10 100 11 44 12 20320 15 22909 18 19990 21 30028
在GO語言中Unicode字元占4個位元組,故輸出結果是16行。
1.5.5、字元串截取
本質上就是數組切片,這在後面的數組切片中會詳細說明,這裡只是舉例:
package main func main() { str := "Hello World,你好世界" newStr := str[1:3] //從第1個位元組開始(含),讀到取到第3個位元組(含) println(newStr) }
運行結果
el
需要留意的是這種字元串截取,實際是以位元組的方式截取的,漢字占3個位元組,可以嘗試下麵的代碼看看結果如何
package main func main() { str := "Hello World,你好世界" newStr := str[12:15] println(newStr) }
1.5.6、字元串搜索
正向搜索首次出現的子字元串,示例:
package main import "strings" func main() { str := "Hello World,你好世界" pos := strings.Index(str, "世界") pos2 := strings.Index(str, "o") println(pos, pos2) //返回子字元串出現的位置 }
運行結果
18 4
反向搜索首次出現的子字元串,示例:
package main import "strings" func main() { str := "Hello World,你好世界" pos := strings.LastIndex(str, "好") pos2 := strings.LastIndex(str, "o") println(pos, pos2) //返回子字元串出現的位置 }
運行結果
15 7
我們可以看出在搜索子字元串時是以位元組的方式遍歷,漢字占3個位元組
1.5.7、字元串拼接
在前面我們知道字元串拼接可以用+
來處理,簡單直觀,但這種方式的性能並不好,因為每次將兩個字元串拼接時實際上會生成一個全新的字元串。在GO語言中也有類似於 StringBuilder(可變字元串) 的機制來進行高效的字元串連接,示例:
package main import ( "bytes" "fmt" ) func main() { firstString := "您好" secondString := "世界" // 聲明位元組緩衝 var stringBuilder bytes.Buffer // 把字元串寫入緩衝 stringBuilder.WriteString(firstString) stringBuilder.WriteString(secondString) // 將緩衝以字元串形式輸出 fmt.Println(stringBuilder.String()) }
運行輸出
您好世界
1.6、字元型
字元串中的每一個元素叫做“字元”,在遍歷或者單個獲取字元串元素時可以獲得字元。字元(Character)是各種文字和符號的總稱,包括各國家文字、標點符號、圖形符號、數字等。
Go語言的字元有以下兩種:
- 一種是 uint8 類型,或者叫 byte(實際上是uint8的別名) 型,代表UTF-8字元串的單個位元組的值,值對應ASCII 碼。
- 另一種是 rune 類型,代表一個Unicode字元,出於簡化語言的考慮,Go語言的多數API都假設字元串為UTF-8編碼,當需要處理中文、日文或者其他複合字元時,則需要用到 rune 類型。rune 類型等價於 int32 類型。關於rune相關的操作,可查閱Go標準庫的unicode包。另外unicode/utf8包也提供了UTF8和Unicode之間的轉換。儘管Unicode字元在標準庫中有支持,但實際上較少使用。
在 ASCII 碼表中,A 的值是 65,使用 16 進位表示則為 41,所以下麵的寫法是等效的:
package main func main() { //在 ASCII 碼表中,A 的值是 65,使用 16 進位表示則為 41,所以下麵的寫法是等效的: var ch byte = 'A' //字元使用單引號括起來 var ch2 byte = 65 var ch3 byte = '\x41' //(\x 總是緊跟著長度為 2 的 16 進位數) var ch4 byte = '\101' //另外一種可能的寫法是 \後面緊跟著長度為 3 的八進位數,例如 \377。 println(ch, ch2, ch3, ch4) }
在Go語言中,Unicode字元在記憶體中也是使用 int 來表示。在文檔中,一般使用格式 U+hhhh 來表示,其中 h 表示一個 16 進位數,例如:
package main import "fmt" func main() { //在書寫 Unicode 字元時,需要在 16 進位數之前加上首碼\u或者\U。因為 Unicode 至少占用 2 個位元組,所以我們使用 int16 或者 int 類型來表示。如果需要使用到 4 位元組,則使用\u首碼,如果需要使用到 8 個位元組,則使用\U首碼。 var ch int = '\u0041' var ch2 int = '\u03B2' var ch3 int = '\U00101234' fmt.Printf("%d - %d - %d\n", ch, ch2, ch3) // integer fmt.Printf("%c - %c - %c\n", ch, ch2, ch3) // character fmt.Printf("%X - %X - %X\n", ch, ch2, ch3) // UTF-8 bytes fmt.Printf("%U - %U - %U", ch, ch2, ch3) // UTF-8 code point }
運行結果:
65 - 946 - 1053236 A - β -