鍍金池/ 教程/ GO/ 4.5 基本類型和運算符
4.7 strings 和 strconv 包
13.6 啟動外部命令和程序
?# 11.4 類型判斷:type-switch
12.1 讀取用戶的輸入
10.6 方法
12.2 文件讀寫
13 錯誤處理與測試
9.3 鎖和 sync 包
12.3 文件拷貝
?# 11.7 第一個例子:使用 Sorter 接口排序
?# 11.5 測試一個值是否實現(xiàn)了某個接口
6.4 defer 和追蹤
12.10 XML 數(shù)據(jù)格式
13.10 性能調試:分析并優(yōu)化 Go 程序
?# 11.1 接口是什么
2.2 Go 環(huán)境變量
2.6 安裝目錄清單
2.5 在 Windows 上安裝 Go
11.11 Printf 和反射
1.2 語言的主要特性與發(fā)展的環(huán)境和影響因素
9.0 包(package)
7.4 切片重組(reslice)
13.2 運行時異常和 panic
10.2 使用工廠方法創(chuàng)建結構體實例
12.8 使用接口的實際例子:fmt.Fprintf
2.4 在 Mac OS X 上安裝 Go
3.8 Go 性能說明
7.2 切片
8.0 Map
3.1 Go 開發(fā)環(huán)境的基本要求
5.6 標簽與 goto
6.10 使用閉包調試
9.5 自定義包和可見性
4.3 常量
?# 11.2 接口嵌套接口
6.5 內(nèi)置函數(shù)
前言
10.8 垃圾回收和 SetFinalizer
2.8 Go 解釋器
13.7 Go 中的單元測試和基準測試
6.8 閉包
4.9 指針
13.1 錯誤處理
10.1 結構體定義
5.1 if-else 結構
6.6 遞歸函數(shù)
9.9 通過 Git 打包和安裝
2.7 Go 運行時(runtime)
10.7 類型的 String() 方法和格式化描述符
3.7 其它工具
9.6 為自定義包使用 godoc
11.12 接口與動態(tài)類型
13.3 從 panic 中恢復(Recover)
10.3 使用自定義包中的結構體
11.14 結構體、集合和高階函數(shù)
3.6 生成代碼文檔
9.2 regexp 包
4.1 文件名、關鍵字與標識符
?# 11.6 使用方法集與接口
7.0 數(shù)組與切片
7.1 聲明和初始化
12.11 用 Gob 傳輸數(shù)據(jù)
5.5 Break 與 continue
1.1 起源與發(fā)展
?# 11 接口(Interfaces)與反射(reflection)
6.9 應用閉包:將函數(shù)作為返回值
4.2 Go 程序的基本結構和要素
8.6 將 map 的鍵值對調
6.11 計算函數(shù)執(zhí)行時間
5.0 控制結構
10.5 匿名字段和內(nèi)嵌結構體
4.6 字符串
3.0 編輯器、集成開發(fā)環(huán)境與其它工具
13.8 測試的具體例子
7.6 字符串、數(shù)組和切片的應用
8.4 map 類型的切片
3.9 與其它語言進行交互
7.3 For-range 結構
9.7 使用 go install 安裝自定義包
6.0 函數(shù)
9.8 自定義包的目錄結構、go install 和 go test
6.3 傳遞變長參數(shù)
13.9 用(測試數(shù)據(jù))表驅動測試
11.9 空接口
8.1 聲明、初始化和 make
6.2 函數(shù)參數(shù)與返回值
9.11 在 Go 程序中使用外部庫
3.3 調試器
4.5 基本類型和運算符
?# 11.8 第二個例子:讀和寫
12.5 用 buffer 讀取文件
總結:Go 中的面向對象
11.10 反射包
12.7 用 defer 關閉文件
9.4 精密計算和 big 包
4.4 變量
6.1 介紹
13.4 自定義包中的錯誤處理和 panicking
12.4 從命令行讀取參數(shù)
9.10 Go 的外部包和項目
8.3 for-range 的配套用法
3.5 格式化代碼
10.4 帶標簽的結構體
7.5 切片的復制與追加
?# 11.3 類型斷言:如何檢測和轉換接口變量的類型
5.4 for 結構
4.8 時間和日期
2.3 在 Linux 上安裝 Go
12 讀寫數(shù)據(jù)
6.12 通過內(nèi)存緩存來提升性能
9.1 標準庫概述
12.6 用切片讀寫文件
10 結構(struct)與方法(method)
8.5 map 的排序
12.9 JSON 數(shù)據(jù)格式
13.5 一種用閉包處理錯誤的模式
3.2 編輯器和集成開發(fā)環(huán)境
12.12 Go 中的密碼學
5.2 測試多返回值函數(shù)的錯誤
6.7 將函數(shù)作為參數(shù)
8.2 測試鍵值對是否存在及刪除元素
3.4 構建并運行 Go 程序
2.1 平臺與架構
5.3 switch 結構

4.5 基本類型和運算符

我們將在這個部分講解有關布爾型、數(shù)字型和字符型的相關知識。

表達式是一種特定的類型的值,它可以由其它的值以及運算符組合而成。每個類型都定義了可以和自己結合的運算符集合,如果你使用了不在這個集合中的運算符,則會在編譯時獲得編譯錯誤。

一元運算符只可以用于一個值的操作(作為后綴),而二元運算符則可以和兩個值或者操作數(shù)結合(作為中綴)。

只有兩個類型相同的值才可以和二元運算符結合,另外要注意的是,Go 是強類型語言,因此不會進行隱式轉換,任何不同類型之間的轉換都必須顯式說明(第 4.2 節(jié))。Go 不存在像 C 和 Java 那樣的運算符重載,表達式的解析順序是從左至右。

你可以在第 4.5.3 節(jié)找到有關運算符優(yōu)先級的相關信息,優(yōu)先級越高的運算符在條件相同的情況下將被優(yōu)先執(zhí)行。但是你可以通過使用括號將其中的表達式括起來,以人為地提升某個表達式的運算優(yōu)先級。

4.5.1 布爾類型 bool

一個簡單的例子:var b bool = true

布爾型的值只可以是常量 true 或者 false。

兩個類型相同的值可以使用相等 == 或者不等 != 運算符來進行比較并獲得一個布爾型的值。

當相等運算符兩邊的值是完全相同的值的時候會返回 true,否則返回 false,并且只有在兩個的值的類型相同的情況下才可以使用。

示例:

var aVar = 10
aVar == 5 -> false
aVar == 10 -> true

當不等運算符兩邊的值是不同的時候會返回 true,否則返回 false。

示例:

var aVar = 10
aVar != 5 -> true
aVar != 10 -> false

Go 對于值之間的比較有非常嚴格的限制,只有兩個類型相同的值才可以進行比較,如果值的類型是接口(interface,第 11 章),它們也必須都實現(xiàn)了相同的接口。如果其中一個值是常量,那么另外一個值的類型必須和該常量類型相兼容的。如果以上條件都不滿足,則其中一個值的類型必須在被轉換為和另外一個值的類型相同之后才可以進行比較。

布爾型的常量和變量也可以通過和邏輯運算符(非 !、和 &&、或 ||)結合來產(chǎn)生另外一個布爾值,這樣的邏輯語句就其本身而言,并不是一個完整的 Go 語句。

邏輯值可以被用于條件結構中的條件語句(第 5 章),以便測試某個條件是否滿足。另外,和 &&、或 || 與相等 == 或不等 != 屬于二元運算符,而非 ! 屬于一元運算符。在接下來的內(nèi)容中,我們會使用 T 來代表條件符合的語句,用 F 來代表條件不符合的語句。

Go 語言中包含以下邏輯運算符:

非運算符:!

!T -> false
!F -> true

非運算符用于取得和布爾值相反的結果。

和運算符:&&

T && T -> true
T && F -> false
F && T -> false
F && F -> false

只有當兩邊的值都為 true 的時候,和運算符的結果才是 true。

或運算符:||

T || T -> true
T || F -> true
F || T -> true
F || F -> false

只有當兩邊的值都為 false 的時候,或運算符的結果才是 false,其中任意一邊的值為 true 就能夠使得該表達式的結果為 true。

在 Go 語言中,&& 和 || 是具有快捷性質的運算符,當運算符左邊表達式的值已經(jīng)能夠決定整個表達式的值的時候(&& 左邊的值為 false,|| 左邊的值為 true),運算符右邊的表達式將不會被執(zhí)行。利用這個性質,如果你有多個條件判斷,應當將計算過程較為復雜的表達式放在運算符的右側以減少不必要的運算。

利用括號同樣可以升級某個表達式的運算優(yōu)先級。

在格式化輸出時,你可以使用 %t 來表示你要輸出的值為布爾型。

布爾值(以及任何結果為布爾值的表達式)最常用在條件結構的條件語句中,例如:if、for 和 switch 結構(第 5 章)。

對于布爾值的好的命名能夠很好地提升代碼的可讀性,例如以 is 或者 Is 開頭的 isSorted、isFinished、isVisible,使用這樣的命名能夠在閱讀代碼的獲得閱讀正常語句一樣的良好體驗,例如標準庫中的 unicode.IsDigit(ch)(第 4.5.5 節(jié))。

4.5.2 數(shù)字類型

4.5.2.1 整型 int 和浮點型 float

Go 語言支持整型和浮點型數(shù)字,并且原生支持復數(shù),其中位的運算采用補碼(詳情參見 二的補碼 頁面)。

Go 也有基于架構的類型,例如:int、uint 和 uintptr。

這些類型的長度都是根據(jù)運行程序所在的操作系統(tǒng)類型所決定的:

  • intuint 在 32 位操作系統(tǒng)上,它們均使用 32 位(4 個字節(jié)),在 64 位操作系統(tǒng)上,它們均使用 64 位(8 個字節(jié))。
  • uintptr 的長度被設定為足夠存放一個指針即可。

Go 語言中沒有 float 類型。

與操作系統(tǒng)架構無關的類型都有固定的大小,并在類型的名稱中就可以看出來:

整數(shù):

  • int8(-128 -> 127)
  • int16(-32768 -> 32767)
  • int32(-2,147,483,648 -> 2,147,483,647)
  • int64(-9,223,372,036,854,775,808 -> 9,223,372,036,854,775,807)

無符號整數(shù):

  • uint8(0 -> 255)
  • uint16(0 -> 65,535)
  • uint32(0 -> 4,294,967,295)
  • uint64(0 -> 18,446,744,073,709,551,615)

浮點型(IEEE-754 標準):

  • float32(+- 1e-45 -> +- 3.4 * 1e38)
  • float64(+- 5 1e-324 -> 107 1e308)

int 型是計算最快的一種類型。

整型的零值為 0,浮點型的零值為 0.0。

float32 精確到小數(shù)點后 7 位,float64 精確到小數(shù)點后 15 位。由于精確度的緣故,你在使用 == 或者 != 來比較浮點數(shù)時應當非常小心。你最好在正式使用前測試對于精確度要求較高的運算。

你應該盡可能地使用 float64,因為 math 包中所有有關數(shù)學運算的函數(shù)都會要求接收這個類型。

你可以通過增加前綴 0 來表示 8 進制數(shù)(如:077),增加前綴 0x 來表示 16 進制數(shù)(如:0xFF),以及使用 e 來表示 10 的連乘(如: 1e3 = 1000,或者 6.022e23 = 6.022 x 1e23)。

你可以使用 a := uint64(0) 來同時完成類型轉換和賦值操作,這樣 a 的類型就是 uint64。

Go 中不允許不同類型之間的混合使用,但是對于常量的類型限制非常少,因此允許常量之間的混合使用,下面這個程序很好地解釋了這個現(xiàn)象(該程序無法通過編譯):

示例 4.8 type_mixing.go

package main

func main() {
    var a int
    var b int32
    a = 15
    b = a + a    // 編譯錯誤
    b = b + 5    // 因為 5 是常量,所以可以通過編譯
}

如果你嘗試編譯該程序,則將得到編譯錯誤 cannot use a + a (type int) as type int32 in assignment。

同樣地,int16 也不能夠被隱式轉換為 int32。

下面這個程序展示了通過顯式轉換來避免這個問題(第 4.2 節(jié))。

示例 4.9 casting.go

package main

import "fmt"

func main() {
    var n int16 = 34
    var m int32
    // compiler error: cannot use n (type int16) as type int32 in assignment
    //m = n
    m = int32(n)

    fmt.Printf("32 bit int is: %d\n", m)
    fmt.Printf("16 bit int is: %d\n", n)
}

輸出:

32 bit int is: 34
16 bit int is: 34

格式化說明符

在格式化字符串里,%d 用于格式化整數(shù)(%x%X 用于格式化 16 進制表示的數(shù)字),%g 用于格式化浮點型(%f 輸出浮點數(shù),%e 輸出科學計數(shù)表示法),%0d 用于規(guī)定輸出定長的整數(shù),其中開頭的數(shù)字 0 是必須的。

%n.mg 用于表示數(shù)字 n 并精確到小數(shù)點后 m 位,除了使用 g 之外,還可以使用 e 或者 f,例如:使用格式化字符串 %5.2e 來輸出 3.4 的結果為 3.40e+00

數(shù)字值轉換

當進行類似 a32bitInt = int32(a32Float) 的轉換時,小數(shù)點后的數(shù)字將被丟棄。這種情況一般發(fā)生當從取值范圍較大的類型轉換為取值范圍較小的類型時,或者你可以寫一個專門用于處理類型轉換的函數(shù)來確保沒有發(fā)生精度的丟失。下面這個例子展示如何安全地從 int 型轉換為 int8:

func Uint8FromInt(n int) (uint8, error) {
    if 0 <= n && n <= math.MaxUint8 { // conversion is safe
        return uint8(n), nil
    }
    return 0, fmt.Errorf("%d is out of the uint8 range", n)
}

或者安全地從 float64 轉換為 int:

func IntFromFloat64(x float64) int {
    if math.MinInt32 <= x && x <= math.MaxInt32 { // x lies in the integer range
        whole, fraction := math.Modf(x)
        if fraction >= 0.5 {
            whole++
        }
        return int(whole)
    }
    panic(fmt.Sprintf("%g is out of the int32 range", x))
}

不過如果你實際存的數(shù)字超出你要轉換到的類型的取值范圍的話,則會引發(fā) panic(第 13.2 節(jié))。

問題 4.1 int 和 int64 是相同的類型嗎?

4.5.2.2 復數(shù)

Go 擁有以下復數(shù)類型:

complex64 (32 位實數(shù)和虛數(shù))
complex128 (64 位實數(shù)和虛數(shù))

復數(shù)使用 re+imI 來表示,其中 re 代表實數(shù)部分,im 代表虛數(shù)部分,I 代表根號負 1。

示例:

var c1 complex64 = 5 + 10i
fmt.Printf("The value is: %v", c1)
// 輸出: 5 + 10i

如果 reim 的類型均為 float32,那么類型為 complex64 的復數(shù) c 可以通過以下方式來獲得:

c = complex(re, im)

函數(shù) real(c)imag(c) 可以分別獲得相應的實數(shù)和虛數(shù)部分。

在使用格式化說明符時,可以使用 %v 來表示復數(shù),但當你希望只表示其中的一個部分的時候需要使用 %f。

復數(shù)支持和其它數(shù)字類型一樣的運算。當你使用等號 == 或者不等號 != 對復數(shù)進行比較運算時,注意對精確度的把握。cmath 包中包含了一些操作復數(shù)的公共方法。如果你對內(nèi)存的要求不是特別高,最好使用 complex128 作為計算類型,因為相關函數(shù)都使用這個類型的參數(shù)。

4.5.2.3 位運算

位運算只能用于整數(shù)類型的變量,且需當它們擁有等長位模式時。

%b 是用于表示位的格式化標識符。

二元運算符

  • 按位與 &

    對應位置上的值經(jīng)過和運算結果,具體參見和運算符,第 4.5.1 節(jié),并將 T(true)替換為 1,將 F(false)替換為 0

      1 & 1 -> 1
      1 & 0 -> 0
      0 & 1 -> 0
      0 & 0 -> 0
  • 按位或 |

    對應位置上的值經(jīng)過或運算結果,具體參見或運算符,第 4.5.1 節(jié),并將 T(true)替換為 1,將 F(false)替換為 0

      1 | 1 -> 1
      1 | 0 -> 1
      0 | 1 -> 1
      0 | 0 -> 0
  • 按位異或 ^

    對應位置上的值根據(jù)以下規(guī)則組合:

      1 ^ 1 -> 0
      1 ^ 0 -> 1
      0 ^ 1 -> 1
      0 ^ 0 -> 0
  • 位清除 &^:將指定位置上的值設置為 0。

一元運算符

  • 按位補足 ^

    該運算符與異或運算符一同使用,即 m^x,對于無符號 x 使用“全部位設置為 1”,對于有符號 x 時使用 m=-1。例如:

      ^2 = ^10 = -01 ^ 10 = -11
  • 位左移 <<

    • 用法:bitP << n
    • bitP 的位向左移動 n 位,右側空白部分使用 0 填充;如果 n 等于 2,則結果是 2 的相應倍數(shù),即 2 的 n 次方。例如:

          1 << 10 // 等于 1 KB
          1 << 20 // 等于 1 MB
          1 << 30 // 等于 1 GB
  • 位右移 >>

    • 用法:bitP >> n。
    • bitP 的位向右移動 n 位,左側空白部分使用 0 填充;如果 n 等于 2,則結果是當前值除以 2 的 n 次方。

當希望把結果賦值給第一個操作數(shù)時,可以簡寫為 a <<= 2 或者 b ^= a & 0xffffffff

位左移常見實現(xiàn)存儲單位的用例

使用位左移與 iota 計數(shù)配合可優(yōu)雅地實現(xiàn)存儲單位的常量枚舉:

type ByteSize float64
const (
    _ = iota // 通過賦值給空白標識符來忽略值
    KB ByteSize = 1<<(10*iota)
    MB
    GB
    TB
    PB
    EB
    ZB
    YB
)

在通訊中使用位左移表示標識的用例

type BitFlag int
const (
    Active BitFlag = 1 << iota // 1 << 0 == 1
    Send // 1 << 1 == 2
    Receive // 1 << 2 == 4
)

flag := Active | Send // == 3

4.5.2.4 邏輯運算符

Go 中擁有以下邏輯運算符:==、!=(第 4.5.1 節(jié))、<<=、>、>=。

它們之所以被稱為邏輯運算符是因為它們的運算結果總是為布爾值 bool。例如:

b3:= 10 > 5 // b3 is true

4.5.2.5 算術運算符

常見可用于整數(shù)和浮點數(shù)的二元運算符有 +、-、*/。

(相對于一般規(guī)則而言,Go 在進行字符串拼接時允許使用對運算符 + 的重載,但 Go 本身不允許開發(fā)者進行自定義的運算符重載)

/ 對于整數(shù)運算而言,結果依舊為整數(shù),例如:9 / 4 -> 2。

取余運算符只能作用于整數(shù):9 % 4 -> 1

整數(shù)除以 0 可能導致程序崩潰,將會導致運行時的恐慌狀態(tài)(如果除以 0 的行為在編譯時就能被捕捉到,則會引發(fā)編譯錯誤);第 13 章將會詳細講解如何正確地處理此類情況。

浮點數(shù)除以 0.0 會返回一個無窮盡的結果,使用 +Inf 表示。

練習 4.4 嘗試編譯 divby0.go。

你可以將語句 b = b + a 簡寫為 b+=a,同樣的寫法也可用于 -=、*=/=、%=。

對于整數(shù)和浮點數(shù),你可以使用一元運算符 ++(遞增)和 --(遞減),但只能用于后綴:

i++ -> i += 1 -> i = i + 1
i-- -> i -= 1 -> i = i - 1

同時,帶有 ++-- 的只能作為語句,而非表達式,因此 n = i++ 這種寫法是無效的,其它像 f(i++) 或者 a[i]=b[i++] 這些可以用于 C、C++ 和 Java 中的寫法在 Go 中也是不允許的。

在運算時 溢出 不會產(chǎn)生錯誤,Go 會簡單地將超出位數(shù)拋棄。如果你需要范圍無限大的整數(shù)或者有理數(shù)(意味著只被限制于計算機內(nèi)存),你可以使用標準庫中的 big 包,該包提供了類似 big.Intbig.Rat 這樣的類型(第 9.4 節(jié))。

4.5.2.6 隨機數(shù)

一些像游戲或者統(tǒng)計學類的應用需要用到隨機數(shù)。rand 包實現(xiàn)了偽隨機數(shù)的生成。

示例 4.10 random.go 演示了如何生成 10 個非負隨機數(shù):

package main
import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    for i := 0; i < 10; i++ {
        a := rand.Int()
        fmt.Printf("%d / ", a)
    }
    for i := 0; i < 5; i++ {
        r := rand.Intn(8)
        fmt.Printf("%d / ", r)
    }
    fmt.Println()
    timens := int64(time.Now().Nanosecond())
    rand.Seed(timens)
    for i := 0; i < 10; i++ {
        fmt.Printf("%2.2f / ", 100*rand.Float32())
    }
}

可能的輸出:

816681689 / 1325201247 / 623951027 / 478285186 / 1654146165 /
1951252986 / 2029250107 / 762911244 / 1372544545 / 591415086 / / 3 / 0 / 6 / 4 / 2 /22.10
/ 65.77 / 65.89 / 16.85 / 75.56 / 46.90 / 55.24 / 55.95 / 25.58 / 70.61 /

函數(shù) rand.Float32rand.Float64 返回介于 [0.0, 1.0) 之間的偽隨機數(shù),其中包括 0.0 但不包括 1.0。函數(shù) rand.Intn 返回介于 [0, n) 之間的偽隨機數(shù)。

你可以使用 Seed(value) 函數(shù)來提供偽隨機數(shù)的生成種子,一般情況下都會使用當前時間的納秒級數(shù)字(第 4.8 節(jié))。

4.5.3 運算符與優(yōu)先級

有些運算符擁有較高的優(yōu)先級,二元運算符的運算方向均是從左至右。下表列出了所有運算符以及它們的優(yōu)先級,由上至下代表優(yōu)先級由高到低:

優(yōu)先級     運算符
 7      ^ !
 6      * / % << >> & &^
 5      + - | ^
 4      == != < <= >= >
 3      <-
 2      &&
 1      ||

當然,你可以通過使用括號來臨時提升某個表達式的整體運算優(yōu)先級。

4.5.4 類型別名

當你在使用某個類型時,你可以給它起另一個名字,然后你就可以在你的代碼中使用新的名字(用于簡化名稱或解決名稱沖突)。

type TZ int 中,TZ 就是 int 類型的新名稱(用于表示程序中的時區(qū)),然后就可以使用 TZ 來操作 int 類型的數(shù)據(jù)。

示例 4.11 type.go

package main
import "fmt"

type TZ int

func main() {
    var a, b TZ = 3, 4
    c := a + b
    fmt.Printf("c has the value: %d", c) // 輸出:c has the value: 7
}

實際上,類型別名得到的新類型并非和原類型完全相同,新類型不會擁有原類型所附帶的方法(第 10 章);TZ 可以自定義一個方法用來輸出更加人性化的時區(qū)信息。

練習 4.5 定義一個 string 的類型別名 Rope,并聲明一個該類型的變量。

4.5.5 字符類型

嚴格來說,這并不是 Go 語言的一個類型,字符只是整數(shù)的特殊用例。byte 類型是 uint8 的別名,對于只占用 1 個字節(jié)的傳統(tǒng) ASCII 編碼的字符來說,完全沒有問題。例如:var ch byte = 'A';字符使用單引號括起來。

在 ASCII 碼表中,A 的值是 65,而使用 16 進制表示則為 41,所以下面的寫法是等效的:

var ch byte = 65 或 var ch byte = '\x41'

\x 總是緊跟著長度為 2 的 16 進制數(shù))

另外一種可能的寫法是 \ 后面緊跟著長度為 3 的八進制數(shù),例如:\377

不過 Go 同樣支持 Unicode(UTF-8),因此字符同樣稱為 Unicode 代碼點或者 runes,并在內(nèi)存中使用 int 來表示。在文檔中,一般使用格式 U+hhhh 來表示,其中 h 表示一個 16 進制數(shù)。其實 rune 也是 Go 當中的一個類型,并且是 int32 的別名。

在書寫 Unicode 字符時,需要在 16 進制數(shù)之前加上前綴 \u 或者 \U。

因為 Unicode 至少占用 2 個字節(jié),所以我們使用 int16 或者 int 類型來表示。如果需要使用到 4 字節(jié),則會加上 \U 前綴;前綴 \u 則總是緊跟著長度為 4 的 16 進制數(shù),前綴 \U 緊跟著長度為 8 的 16 進制數(shù)。

示例 4.12 char.go

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 - β - r
41 - 3B2 - 101234
U+0041 - U+03B2 - U+101234

格式化說明符 %c 用于表示字符;當和字符配合使用時,%v%d 會輸出用于表示該字符的整數(shù);%U 輸出格式為 U+hhhh 的字符串(另一個示例見第 5.4.4 節(jié))。

unicode 包含了一些針對測試字符的非常有用的函數(shù)(其中 ch 代表字符):

  • 判斷是否為字母:unicode.IsLetter(ch)
  • 判斷是否為數(shù)字:unicode.IsDigit(ch)
  • 判斷是否為空白符號:unicode.IsSpace(ch)

這些函數(shù)返回一個布爾值。包 utf8 擁有更多與 rune 相關的函數(shù)。

譯者注:關于類型的相關講解,可參考視頻教程 《Go編程基礎》 第 3 課:類型與變量

鏈接