[英]How does the Go compiler know which bytes in a byte slice should be grouped together into one rune?
例子:
func main() {
byteSlice := []byte{226, 140, 152, 97, 98, 99}
fmt.Println(string(byteSlice))
}
打印出来:
⌘abc
在幕后,Go 是如何知道前三个字节 - 226, 140, 152
- 应组合为单个 uint32 符文: ⌘
,而其余字节应转换为三个单独的符文: a
、 b
和c
, 分别?
通过将UTF-8 编码解码为 UTF-32。
查看每个八位字节的前导位,屏蔽标记位,并将数据位与位移位和按位或相结合,这很简单。
码点↔UTF-8转换
第一个代码点 | 最后一个代码点 | 字节 1 | 字节 2 | 字节 3 | 字节 4 |
---|---|---|---|---|---|
U+0000 | U+007F | 0xxxxxxx | |||
U+0080 | U+07FF | 110xxxx | 10xxxxxx | ||
U+0800 | U+FFFF | 1110xxxx | 10xxxxxx | 10xxxxxx | |
U+10000 | U+10FFFF | 11110xxx | 10xxxxxx | 10xxxxxx | 10xxxxxx |
There's rather more to it than that, though, due to various Unicode normalization forms, and the possible presence of combining marks (eg, e
/U+0065 followed by the combining mark ´
/U+0301 results in the Unicode code point (rune ) 为é
/U+00E9。
有趣的是,如果您查看unicode/utf8
的来源,似乎DecodeRune()
和DecodeRuneInString()
https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/unicode/utf8/utf8.go;l=151
https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/unicode/utf8/utf8.go;l=199
看起来,由于代码对组合标记没有任何作用,它有一个基本假设,即字符串中的八位字节在 Unicode 规范化形式 C (规范分解后跟规范组合),所以你永远不会看到组合标记.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.