Go 的 rune byte 和 string
阿新 • • 發佈:2019-01-02
rune
、byte
和string
都是Go
的內建型別
byte
- byte是
uint8
的別名,在所有方面都等同於uint8
- 按慣例,它用於區分位元組值和8位無符號整數值。
- byte是
rune
rune
是int32
的別名,在所有方面都等同於int32
- 按慣例,它用於區分字元值和整數值。
string
- string是所有8位位元組字串的集合,通常但不一定代表UTF-8編碼的文字
- 字串可能為空,但是不能為
nil
- 字串型別的值是不可變的
- 由上面得解釋我們大概可以明白
rune
可以表示得比byte
多string
型別的底層是一個byte
陣列- 以上解釋都來此
Go
原始碼註釋
-
剛剛上面標註了位元組和字元,現在我們來梳理字元和位元組的概念
-
儲存單位 位元組
- 計算機儲存資訊的最小單位,稱之為位
bit
,二進位制的一個0
或1
叫一位 - 計算機儲存容量基本單位是位元組
Byte
,8個二進位制位組成1
個位元組
- 計算機儲存資訊的最小單位,稱之為位
-
資訊表示單位 字元
- 字元 是一種符號,像 英文
a
阿
就是不同字元 - 不同的字元在不同的編碼格式下,所需要的儲存單位不一樣
ASCLII
編碼中一個英文字母一位元組,一個漢字兩位元組UTF-8
編碼中 一個英文字母一位元組,一個常見漢字3位元組,不常用的超大字符集漢字4位元組
- 字元 是一種符號,像 英文
Go
原始碼檔案預設採用Unicode
字符集,Unicode
碼點和記憶體中位元組序列的變換實現使用了UTF-8
,這使得Go
程式設計無需考慮編碼轉換的問題非常方便- 從編碼上來分析
byte
用來強調一個位元組代表的資料(例如字元a
就是97
rune
用來表示Unicode
的碼點,即一個字元
- 通俗一點
byte
只能操作簡單的字元,不支援中文操作rune
能操作任何字元
- 程式碼演示
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
str := "hello 世界!"
fmt.Println(str)
fmt.Println(len(str))
fmt.Println(utf8.RuneCountInString(str))
fmt.Println(str[1])
fmt.Println(string(str[1]))
fmt.Println(str[1:])
fmt.Println(str[7:])
}
*************************************
輸出
hello 世界!
13
9
101
e
ello 世界!
��界!
- 會輸出
hello 世界!
,這證明Go
是UTF-8
編碼的,輸出長度為13
這說明了一個漢字3位元組 - 輸出
ello 世界!
說明string
底層的資料結構是陣列 - 輸出
��界!
說明string
底層是一個byte
陣列,不然不會亂碼
package main
import "fmt"
func StrChangeByRune(str *string, i int, ch rune) {
temp := []rune(*str)
temp[i] = ch
*str = string(temp)
}
func StrChangeByByte(str *string, i int, ch byte) {
temp := []byte(*str)
temp[i] = ch
*str = string(temp)
}
func main() {
str := "你好 hello"
str1 := "你好 hello"
StrChangeByRune(&str, 1, 'A')
StrChangeByByte(&str1, 1, 'A')
fmt.Println(str)
fmt.Println(str1)
}
*******************************
輸出
你A hello
�A�好 hello
- 由輸出
你A hello
和�A�好 hello
可以看出 byte
的操作單位是一個位元組,可以理解為一個英文字元rune
的操作單位是一個字元,不管這個字元是什麼字元