rune是int32的別名類型,一個值就代表一個Unicode字符。
byte是uint8的別名類型,一個值就是一個ASCII碼值。
rune類型的值在底層都是由一個 UTF-8 編碼值來表達的。
瞭解下什麼是Unicode字符和ASCII碼:
1、簡單理解,我們平時接觸到的中英日文,或者複合字符,都是Unicode字符。比如,'G'、'o'、'愛'、'好'、'者'就是一個個Unicode字符。
2、字符在計算機中存儲時需要使用二進制數來表示。所以人們定義了一張表,將我們用到的字符用一個二進制數值表示。這就是ASCII碼錶的由來。
UTF-8 編碼方案會把一個 Unicode 字符編碼為一個長度在 1~4 以內的字節序列。所以,一個rune類型值代表了1~4個長度的byte數組。
案例:
func main() {
str := "Go愛好者"
fmt.Printf("The string: %q\n", str)
fmt.Printf(" => runes(char): %q\n", []rune(str))
fmt.Printf(" => runes(hex): %x\n", []rune(str))
fmt.Printf(" => bytes(hex): [% x]\n", []byte(str))
}
The string: "Go愛好者"
=> runes(char): ['G' 'o' '愛' '好' '者']
=> runes(hex): [47 6f 7231 597d 8005]
=> bytes(hex): [47 6f e7 88 b1 e5 a5 bd e8 80 85]
字符串值"Go愛好者"如果被轉換為[]rune類型的值的話,其中的每一個字符(不論是英文還是中文)就都會獨立成為一個rune類型的元素值。如打印出的第二行內容。
又由於,每個rune類型的值在底層都是由一個 UTF-8 編碼值來表達的,如第三行
把每個字符的 UTF-8 編碼值都拆成相應的字節序列,如第四行,因為一箇中文字符的 UTF-8 編碼值需要用三個字節來表達。
總結:
一個string類型的值既可以被拆分為一個包含多個字符的序列,也可以被拆分為一個包含多個字節的序列。前者可以由一個以rune為元素類型的切片來表示,而後者則可以由一個以byte為元素類型的切片代表。
補充:
fmt.Println("\u0070\x68\x65\x72")
fmt.Println(`"\u0070\x68\x65\x72"`)
fmt.Println(strconv.Unquote(`"\u0070\x68\x65\x72"`))
輸出:
pher
"u0070x68x65x72"
pher <nil>