byte 和 rune
byte 是 uint8 的別名,其字面量是 8 位整數值,byte 切片相比于不可變的 string 方便常用許多,它可以更改每個位元組或字符,這對于處理檔案內容(無論是文本檔案、二進制檔案還是來自網路的I/O流)非常有效,byte 切片是一個可變的位元組序列
rune 是 int32 的別名,其字面量是 32 位整數值,用來表示 Unicode 字符編碼,rune 類似于 byte,不同點在于 rune 每個索引是一個字符而不是一個位元組,rune 切片是對位元組片的重新分組使得每個索引都是一個字符,
如果你處理的文本檔案有很多非 ascii 字符,比如中文文本、數學公式或帶有表情符號的文本,使用 rune 是最好的,
rune 也是從字串中獲取子字串的理想選擇,它支持 Unicode 字符,沒有資料損壞的風險,
對于 []rune,len()和索引都是基于 rune(int32)的,
當你將 []rune 轉換為 string 時,每個 rune 成為字串中的一個 utf-8 字符,
byte 和 rune 的區別
func main() {
s := "G?"
sample := "H哈"
sByte := []byte(s)
sRune := []rune(s)
sampleByte := []byte(sample)
sampleRune := []rune(sample)
fmt.Printf("%s\nsByte: %d\nsRune: %d\n", s, sByte, sRune)
fmt.Println("------")
fmt.Printf("%s\nsampleByte: %d\nsampleRune: %d\n", sample, sampleByte, sampleRune)
}
可以看到rune 中非 ASCII 碼字符的 Unicode 編碼為 1-3 位元組,與 ASCII 碼字符的位元組數不一定相同,
string
string 是不可變的 byte 切片,因為Go中的源代碼使用 utf-8 編碼,因此每個字串也使用utf-8編碼,即 string 字面量是 utf-8 編碼,以 byte 為單位的,string 中的每個字符實際占用 1-3 個位元組,而每個 rune 占 4 個位元組,
- 使用 rune() 可把 byte 為單位的字符轉換為 rune 字符,對于 ASCII 字符來說,rune 值和 byte 值相同,而對于 Unicode 編碼的字符來說便不同了,
- 使用 []rune() 將 string 轉換 rune 陣列,當將字串轉換為 rune 切片時,字串中的每個 utf-8 字符被轉換為一個 rune,從而獲得包含字串 Unicode 編碼字符的新切片,
- 對于 string,len()和索引都是基于 byte(unint8)的
- 在 Go 中將字串轉換為 rune 切片是一個標準操作,沒有資料損壞的風險,
字串是處理短位元組或字符序列比較好的方法,每次對字串進行操作(例如查找替換字串或接受子字串)時,都會創建一個新的字串,如果字串非常大,例如檔案內容,則效率非常低,
string 中索引字符
例如我們先看下面程式:
func main() {
sample := "Hel哈"
for i := 0; i < len(sample); i++ {
fmt.Print(sample[i], " ")
}
fmt.Println()
fmt.Printf("%s\t的位元組長度: %d\n", sample, len(sample))
fmt.Printf("哈\t字符的位元組長度: %d\n", utf8.RuneLen('哈'))
fmt.Printf("%s\t的字符長度: %d\n", sample, utf8.RuneCountInString(sample))
}
輸出:
72 101 108 229 147 136
Hel哈 的位元組長度: 6
哈 字符的位元組長度: 3
Hel哈 的字符長度: 4
可以看出字串的長度(len)和字串的字符長度(RuneCountInString)是不同的,因為字串是位元組切片,Go 默認 UTF-8,存盤非 ASCII 字符時,每個字符則會存盤 1-3 個位元組,所以想要正確地索引字串中的字符有以下兩種方法:
- 將字串轉換為 rune 切片
- 使用 range 運算子迭代 Unicode 字符
也就是說對字串進行 rang 迭代,是字符迭代,而不是位元組迭代,
關于編碼的一些方法
utf8.ValidRune(chr) 判斷 chr 是否可以編碼為合法的utf-8序列,
utf8.RuneLen(chr) 查看字符 chr 的位元組長度
utf8.RuneCount() 查看位元組陣列中按照 rune 單位的字符長度
utf8.RuneCountInString 查看字串按照 rune 單位的長度
參考資料
- Golang: How To Convert String To Rune in Go Example
- go - What is a rune? - Stack Overflow
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/296999.html
標籤:Go
上一篇:語言 define 定義常量 - C語言零基礎入門教程
下一篇:Java 多執行緒
