string类型值的底层是如何表达的?
- 一个string类型的值是有一系列向对应的Unicode代码点的UTF-8编码值来表达的
在Go语言中,一个String类型的值既可以拆分成一个包含多个字符的序列,也可拆分成一个包含多个字节的序列
- 多个字符序列:由一个rune为元素类型的切片表达
- 多个字节序列:由一个以byte为元素类型的切片表达
rune是Go语言特有的一个基本数据类型,它的一个值就代表一个字符,即:一个Unicode字符
- ‘G’、 ‘o’、’爱’、’好’、’者’ 代表的就死一个Unicode字符
- UTF-8 编码方案会把Unicode字符编码为一个长度在[1,4]范围内的字节序列
- rune类型的生命: type rune = int32 它实际就是int32类型的一个别名类型
package main
import (
"fmt"
)
func main() {
str := "Go爱好者"
fmt.Printf("The string: %q\n", str) // Go爱好者
fmt.Printf(" => runes(char): %q\n", []rune(str)) // ['G' 'o' '爱' '好' '者']
fmt.Printf(" => runes(hex): %x\n", []rune(str)) // [47 6f 7231 597d 8005]
fmt.Printf(" => bytes(hex): [% x]\n", []byte(str)) // [47 6f e7 88 b1 e5 a5 bd e8 80 85]
}
从上面示例代码可见:
- 字符串 “Go爱好者” 如果被转换为 []rune 类型的值,其中每一个字符都是一个独立的rune类型的元素值
- 每个rune类型的值在底层都是由UTF-8编码值来表达
- UTF-8 编码的值由 [1,4] 个字节组成,因此最后一句打印的值要比倒数第二句长很多
使用range子句的for语句遍历字符串
str := "Go爱好者"
for i, c := range str {
fmt.Printf("%d: %q [% x]\n", i, c, []byte(string(c)))
}
打印的结果为:
0: 'G' [47]
1: 'o' [6f]
2: '爱' [e7 88 b1]
5: '好' [e5 a5 bd]
8: '者' [e8 80 85]
_每次迭代都会打印出两个值:**_
- 第二个值是 rune类型的值
- 第一个值则是 rune类型值的起始字节 在 字符串字节中的位置