前言
在大部分的程式語言中,資料會有資料型態 (data type)。資料型別用來界定資料在電腦程式中所占的記憶體大小及合乎規範的操作。本文介紹 Golang 中可用的資料型別。
布林數 (Boolean)
布林型態 (bool
) 用來表達布林運算的概念。在 Go 語言中,布林型態只有兩個值:
true
(表示真)false
(表示偽)
我們很少在程式中直接以實字來寫死真值或偽值,重點反而在於了解什麼時候條件句 (conditional) 會轉為真值,什麼時候會轉為偽值。我們會在後文介紹條件句的寫法。
數字 (Number) 相關的型別
Golang 的數字型態
數字型態 (numeric types) 用來表示數字。在 Go 語言中有以下數字型態:
- 無號整數
uint8
uint16
uint32
uint64
uint
(32 或 64 位元)
- 帶號整數
int8
int16
int32
int64
int
(32 或 64 位元)
- 浮點數
float32
float64
- 複數
complex64
complex128
理想上,應該用貼近範圍的數字型別,以節約運算資源。但在現在的桌機上跑 Golang 程式,運算資源基本上都是足夠的,就不需要對型態斤斤計較。日常使用上,選擇 uint
、int
、float64
等型別即可。
如果要計算的數字超過本節所列的範圍,就要用大數 (big number) 函式庫去運算,像是 math/big。由於大數是用軟體去模擬的,會比內建的數字型態來得慢。
整數 (Integer)
整數不限於十進位。以下是 Golang 合法的數字系統:
- 二進位:
0B0001
或0b0001
- 八進位:
0O777
(注意大寫O
) 或0o777
- 十進位:
12345
- 十六進位:
0XFF
或0xFF
數字間可使用底線 _
來加強易讀性。底線不影響數字的值。
數字型態的重點在於其範圍,在運算的過程中超出該型別的範圍時會引發溢位 (overflow) 或下溢 (underflow),造成錯誤的計算結果。
以下是無號整數的範圍:
資料型別 | 下限 | 上限 |
---|---|---|
uint8 | 0 | 255 |
uint16 | 0 | 65535 |
uint32 | 0 | 4.29 * 10 的 9 次方 |
uint64 | 0 | 1.84 * 10 的 19 次方 |
注意無號整數的下限皆為 0。
以下是帶號整數的範圍:
資料型別 | 下限 | 上限 |
---|---|---|
int8 | -128 | 127 |
int16 | -32768 | 32767 |
int32 | -2.14 * 10 的 9 次方 | 2.14 * 10 的 9 次方 |
int64 | -9.22 * 10 的 18 次方 | 9.22 * 10 的 18 次方 |
由於帶號整數有正負兩邊,故在單邊的範圍為無號整數的一半。
浮點數 (Floating-Point Number)
浮點數可用十進位或 (相對少見的) 十六進位來表示。
以下則是浮點數的範圍:
資料型別 | 標準 | 精準度 | 位數 |
---|---|---|---|
float32 | IEEE-754 32 位元 | 最多 6 位數 | 10 的 38 次方 |
float64 | IEEE-754 64 位元 | 最多 15 位數 | 10 的 308 次方 |
浮點數可表示較高位數的數字,但其精確度有所限制。
複數 (Complex Number)
至於複數的範圍和浮點數相同,但分為實數及虛數兩部分,故位元數為浮點數的兩倍。
字串 (String) 相關的型別
Go 語言有三種字串型態:
string
byte
rune
在預設情形下,應該優先使用 string
型別,除非有明確的理由,才會使用另外兩種型別。
string
是以 UTF-8 編碼來處理的字串,string
的值視為單值而非字元陣列。相對來說,byte
則保持字串原始的內容,不處理編碼。rune
則是將字串以 Unicode code point 切開時所用的型別。這篇文章有詳細的說明,有興趣的讀者可以看一看。
陣列 (Array) 和切片 (Slice)
陣列和切片是以數字為索引 (index) 的線性容器。兩者的差別主要在於陣列的長度是固定的,而切片可以伸縮長度。兩者的語法幾乎雷同,但使用切片的時機會多於陣列。
映射 (Map)
映射是以鍵值對 (key-value pair) 為元素的非線性資料結構,主要的好處是可以透過鍵 (key) 快速取得值 (value),而不用逐一走訪所有元素。
結構 (Struct)
透過結構,我們可以在單一複合型別中存取多個欄位 (field),用來表達基礎型別無法表達的概念。在 Golang 中,結構也是大部分基於物件的程式設計 (object-based programming) 中會用到的特性。
指標 (Pointer)
指標本身儲存是指向其他值的位址,而非值。透過指標可間接存取值。在多數情形下,傳遞指標的開銷會比直接傳遞資料來得小,在函式中會藉由傳遞指標來間接傳遞較大的資料。
函式 (Function)
在 Go 語言中,函式也可做為資料。其意義在於 Go 語言可使用函數式程式設計 (functional programming) 的概念來撰寫程式。雖然 Golang 不強調函數式程式設計的範式,但 Golang 的確可以用這種思維來寫程式。
通道 (Channel)
通道用於共時性 (concurrency) 程式中,在 goroutine 之間傳遞資料。共時性程式的優點在於可充分利用多核心 CPU。Golang 的共時性程式會比傳統上基於執行緒的程式來得簡單。
結語
透過本文,讀者應該對 Go 語言的型態有一些概念了。雖然我們現在尚未動手寫程式,請讀者先耐著性子讀完本文。因為資料型態是程式設計中基本的概念,在實際撰寫程式時自然會用到。