• Go 之为什么 rune 是 int32 的别名而不是 uint32 的别名


    我对这个问题其实也是一直有疑问的,毕竟像 byte 都是 uint8 的别名。然后找了一些问答资料,不知道还没有没其他更好的解释。

    范围足够

    在 Unicode 字符集中,一个字符的码点范围是从 U+0000 到 U+10FFFF,共计 1114112 个码点,可以用 32 位的整数类型来表示。 Unicode 转换格式,虽然使用的是 4 字节(32bit),但实际上只用到了 21bit。所以 int32 是足够包含该编码范围的。

    扩展兼容

    使用 int32 类型能有效避免符号扩展等不必要的类型转换,以及提供向下兼容的能力。

    算术运算方便

    定义为 int32 是为了方便 rune 类型进行算数运算。

    1. package main
    2. import "fmt"
    3. func main() {
    4. s := "hello world"
    5. a := []rune(s)
    6. fmt.Println(a)
    7. b := a[1] - a[0]
    8. if b < 0 {
    9. fmt.Println(b)
    10. }
    11. }

    比如像 byte 进行算术运算时,就会出现溢出的情况(所以也建议大家尽量不要拿 byte 的运算结果做条件判断等)。

    1. package main
    2. import "fmt"
    3. func main() {
    4. s := "hello world"
    5. a := []byte(s)
    6. fmt.Println(a) // [104 101 108 108 111 32 119 111 114 108 100]
    7. if a[1] - a[0] > 0 {
    8. fmt.Println("a[1] > a[0]", a[1] - a[0]) // a[1] > a[0] 253
    9. }
    10. if a[0] - a[1] > 0 {
    11. fmt.Println("a[0] > a[1]", a[0] - a[1]) // a[0] > a[1] 3
    12. }
    13. }

    uint8 别名 byte

    既然如此,还有一个疑问,为什么 Go 中 byte 是 uint8 的别名,而不是 int8 的别名呢?

    哈哈,这个就不得不提到 UTF-8 编码了,正好也是 Go 默认的编码方式。

    UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用 1~4 个字节表示一个符号,根据不同的符号而变化字节长度。

    UTF-8 的编码规则很简单,只有二条:

    • 对于单字节的符号,字节的第一位设为 0,后面 7 位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的
    • 对于 n 字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。
    1. package main
    2. import (
    3. "fmt"
    4. )
    5. func main() {
    6. s := "好"
    7. b := []byte(s)
    8. fmt.Println(b) // [229 165 189]
    9. for _, c := range b {
    10. fmt.Printf("%b ", c) // 11100101 10100101 10111101
    11. }
    12. }

    这样的话,在 UTF-8 编码下使用 byte 表示非 ASCII 字符的话(需要多字节表示),就不得不涉及到字节高位的情况了,而字节高位的表示显然是用 int8 无法处理的。

  • 相关阅读:
    Java虚拟机对象创建的过程
    深度学习之基于Pytorch的昆虫分类识别系统
    Git 创建分支、合并分支
    IDEA 2021.3.3最新激活破解教程(可激活至2099年,亲测有效)
    [RK3568 Android11]火焰图详解
    lv5 嵌入式开发-10 信号机制(下)
    【ElementUI】ElementUI Tooltip 根据内容判断是否显示、文字提示自定义样式
    华为畅享系列多款产品升级HramonyOS 4.2版本,一篇带你解读
    (十三)【Jmeter】线程(Threads(Users))之tearDown 线程组
    【window 安装多环境python冲突 -已解决】
  • 原文地址:https://blog.csdn.net/TomorrowAndTuture/article/details/137970535