rune

作者: JunChow520 | 来源:发表于2021-04-20 01:04 被阅读0次

    Unicode

    Unicode统一码又称为万国码或单一码,是计算机科学领域中的一项业界标准,包含字符集、编码方案等。

    Unicode统一码是为了解决传统字符编码方案的局限而产生,它为每种语言中每个字符设定了统一且唯一的二进制编码,以满足跨语言、跨平台进行文本转换和处理的要求。

    Unicode统一码是基于通用字符集(Universal Character Set)标准发展而来的,Unicode字符集简称为UCS(Unicode Character Set),早期的Unicode标准有UCS-2、UCS-4说法。

    Unicode编码系统可分为编码方式和实现方式两个层次

    编码方式上,Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案,采用数字0到0x10FFFF来映射所有的字符,最多可容纳1114112个字符。从数字0开始为每个符号会指定一个编号,这个编号叫做Code Point,翻译为码元、码位、码点都有,都是指可以分配给字符的数字。码点规定使用U+随后紧接着十六进制数来表示。

    例如:Unicode码点0的符号是null,表示所有二进制位都是0。

    U+0000 = null
    

    目前最新版的Unicode7.0共收录了109449个符号,中日韩文字位74500个,东南亚文字占了全球现有符号的2/3。如此多的符号Unicode并不是一次性定义的,而是采用分区定义的方式。规定每个区可存放65536个字符,一个区又称为一个平面(plane),目前共有17个平面。在所有字符为最前面的65535个字符位称为基本平面(BMP),码点范围从0到65535,十六进制表示从U+0000到U+FFFF。基本平面存放着最常用的字符,这也是Unicode最先定义和公布的一个平台。剩余字符都存放在辅助平面(SMP),码点范围U+010000到U+10FFFF。

    实现方式上,Unicode指规定了每个字符的码点,具体采用什么样的字节序表示码点就涉及到了编码方法。编码方式目的将数字表示为程序中数据,最直观的编码方法是每个码点使用4个字节表示,字节内容一一对应码点,这种编码方法就叫做UTF-32。

    比如:码点0的UTF-32表示方式

    U+0000 = 0x00 00 00 00
    

    UTF-32编码方案的优点在于,转换规则简单直观,查找效率高,时间复杂度O(1)。缺点在于浪费空间,同样内容的英文文本会比ASCII编码大4倍。这个缺点很致命,导致实际上没有人使用,比如HTML5标准就明文规定,网页编码不得采用UTF-32。


    UTF是UCS Transformation Format的缩写,翻译为Unicode字符集转换格式,即怎样将Unicode定义的数字转换称为程序数据。

    UTF-8

    为了节省空间就导致了UTF-8的诞生,UTF-8是一种变长的编码方法,字符长度从1个字节到4个字节不等。越是常用的字符,字节越短,最前面的128个字符只使用1个字节表示,与ASCII码完全相同。

    UTF-8又称为8位元,是针对Unicode的一种可变长度字符编码。可以用来表示Unicode标准中的任何字符,其编码中的第一个字节仍与ASCII相容。

    UTF-8使用1到4个字节为每个字符编码

    • 一个ASCII字符,只需要1字节编码。
    • 带变音符号的拉丁文、希腊文、西里尔等字母,需要2字节编码。
    • 中日韩文字、东南亚文字、中东文字等包含大量常用字,需要3字节编码。
    • 极少使用的语言会使用4字节编码

    byte

    字节是计算机用于计量存储容量的一种单位,是二进制数据的单位,一个字节通常8位长。Go语言中byteuint8类型的别名,一个字节存储8位无符号数,存储的数值范围从0到255。byte可用于表示ASCII码表中的一个字符,传统ASCII编码的字符每个只占1字节。

    数据类型 别名 数据范围 描述
    uint8 byte 0~255 可表示ASCII字符

    例如:ASCII码表中大写字母A对应的十进制数值为65,对应十六进制数值为41。

    var b byte = 65
    fmt.Printf("ascii = %v, unicode = %U, char = %c, hex = %x\n", b, b, b, b)
    // ascii = 65, unicode = U+0041, char = A, hex = 41
    

    注意:格式化说明符%c表示字符(char),当与字符配合使用时%v%d会输出字符对应的整数,%U输出格式为U+hhhh的字符串。

    char

    和其它语言不同的是Go语言中没有字符这种数据类型,字符只是整数的特殊用例。在Go中具两个用来表示字符的整型别名分别是byterune

    type byte = uint8
    type rune = int32
    
    • byteuint8的别名,长度为1个字节,用来表示ASCII字符。
    • runeint32的别名,长度为4个字节,用来表示UTF-8编码的Unicode。

    既然byterune都能表示字符,为什么还需要两种呢?由于byte占用1个字节,因此可用来表示ASCII字符。Go默认编码方式为UTF-8,UTF-8采用的是变长的编码方式,字符长度从1到4个字节不等。对于具有2个字节以上的字符,此时byte就无能无力了。因此就需要rune

    string

    Go语言中字符串string本质上是一个只读的字节切片,由于是只读的因此字符串内容一旦被创建是不能被修改的。如需修改需将字符串先转换为[]byte字节切片或[]rune符文切片再操作。

    当使用for...range遍历字符串时,Go会自动将字符串转换为[]rune后再执行遍历,即按字符遍历。而使用for循环字符串时,不会发生自动转换,默认会按字节遍历。

    例如:按字节遍历字符串

    s := "字符串str"
    for i := 0; i < len(s); i++ {
        fmt.Printf("%+v %c\n", s[i], s[i])
    }
    
    229 å
    173 ­
    151 �
    231 ç
    172 ¬
    166 ¦
    228 ä
    184 ¸
    178 ²
    115 s
    116 t
    114 r
    

    例如:按字符遍历字符串

    //字符遍历
    s := "字符串str"
    for i, v := range s {
        fmt.Println(i, v, fmt.Sprintf("%c", v))
    }
    
    0 23383 字
    3 31526 符
    6 20018 串
    9 115 s
    10 116 t
    11 114 r
    

    相关文章

      网友评论

          本文标题:rune

          本文链接:https://www.haomeiwen.com/subject/tsxznktx.html