Go 的 rune byte 和 string
-
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" func main() { str := "hello 世界!" fmt.Println(str) fmt.Println(len(str)) fmt.Println(str[1]) fmt.Println(string(str[1])) fmt.Println(str[1:]) fmt.Println(str[7:]) } ************************************* 輸出 hello 世界! 13 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
的操作單位是一個字元,不管這個字元是什麼字元