zoukankan      html  css  js  c++  java
  • Go 语言中的 byte 类型和 rune 类型

    Go 语言中定义字符串要用双引号,而不是单引号,单引号中只能包含一个元素,表示一个字符。

    Go语言中字符有两种类型,分别是:

    1. uint8 类型,或者叫 byte 型,代表了 ASCII 码的一个字符
    2. rune 类型,代表一个 UTF-8 字符

    了解编码知识的应该知道,ASCII 编码字符是1个字节的,而 UTF-8 是可变长的编码,当要表示中文等非 ASCll 编码的字符时,需要使用 UTF-8 编码来保证不会乱码。关于字符编码相关知识,推荐看这篇廖雪峰的介绍 字符编码

    假如我们要遍历输出一个包含中文的字符串时:

    package main
    
    import "fmt"
    
    func main() {
    	str := "hello 世界"
    	for i := 0; i < len(str); i++ {
    		fmt.Println(str[i])
    	}
    }
    

    上述代码的打印结果是:

    104
    101
    108
    108
    111
    32
    228
    184
    150
    231
    149
    140
    

    Go 语言字符串存储的其实是类型为 byte 的只读切片,或者说一个字符串就是一堆字节。在 UTF-8 编码中一个英文字符可以用一个字节存储,一个中文字符需要三个或四个字节存储,而 ASCII 码符号只有 128 个,大于 128 的都不在范围内。上述代码的遍历方式就是以 ASCII 类型来读字符的。

    可以看到输出结果中的前 6 个都是在 ASCII 表中的,但是后 6 个就不在表中了,后面 6 个的每一个字节都不能单独表示一个字符,而是用 3 个在一起才能表示一个字符,明显超出了 ASCII 表的范围,所以当打印具体字符时就会乱码,比如我们现在来打印每一个真实字符,需要使用到占位符 %c

    package main
    
    import "fmt"
    
    func main() {
    	str := "hello 世界"
    	for i := 0; i < len(str); i++ {
    		fmt.Printf("%c", str[i]) // hello ä¸ç
    	}
    }
    

    输出结果为:

    hello ä¸ç
    

    明显乱码了。解释这么多就是为了说明如果字符串中有非 ASCII 码的字符时,就不能使用 byte 来表示字符,需要使用 rune 类型来表示。

    使用 rune 类型来遍历字符串

    在 Go 中,有一个遍历方式是 range,它默认就是以 UTF-8 编码形式去读每一个字符。当涉及到的字符串中含有非英文字符时,可以使用 range 来遍历:

    package main
    
    import "fmt"
    
    func main() {
    	str := "hello 世界"
    	for _, r := range str {
    		fmt.Println(r)
    	}
    }
    

    输出结果为:

    104
    101
    108
    108
    111
    32
    19990
    30028
    

    此时输出的字节编码就是 UTF-8 编码号,UTF-8 编码是包含 ASCII 编码的,所以前 6 个编号还是一样的,后面两个编号分别代表

    修改字符串

    Go 语言中对字符串的修改其实不是对字符串本身的修改,而是复制字符串,同时修改值,即重新分配来内存,需要先将字符串转化成数组,[]byte[]rune,然后再转换成 string 型。

    那么我要说的也很明显了,就是要区别使用 []byte[]rune

    对于全是ASCII编码的字符串,使用 []byte 即可:

    package main
    
    import "fmt"
    
    func main() {
    	str := "abc"
    	s2 := []byte(str)
    	s2[0] = 'b'
    	fmt.Println(string(s2)) //bbc
    }
    
    // string()表示强制类型转换,转换为字符串
    

    对于包含中文等字符的字符串时,那就要用 []rune 了:

    func main() {
        str:="白猫"
        s2:=[]rune(str)
        s2[0]='黑'
        fmt.Println(string(s2)) //黑猫
    }
    

    总结

    在处理字符时,要考虑字符的编码范围,然后根据需要使用 byte 类型或 rune类型。

    byte 类型只能正常输出 ASCII 编码范围的字符;rune 类型可以输出 UTF-8 编码范围的字符。

  • 相关阅读:
    SAP OPEN UI5 Step 8: Translatable Texts
    SAP OPEN UI5 Step7 JSON Model
    SAP OPEN UI5 Step6 Modules
    SAP OPEN UI5 Step5 Controllers
    SAP OPEN UI5 Step4 Xml View
    SAP OPEN UI5 Step3 Controls
    SAP OPEN UI5 Step2 Bootstrap
    SAP OPEN UI5 Step1 环境安装和hello world
    2021php最新composer的使用攻略
    Php使用gzdeflate和ZLIB_ENCODING_DEFLATE结果gzinflate报data error
  • 原文地址:https://www.cnblogs.com/wjaaron/p/14822799.html
Copyright © 2011-2022 走看看