Go 的 rune byte 和 string

  • runebytestring 都是 Go 的内置类型

  • byte
    • byte是uint8的别名,在所有方面都等同于uint8
    • 按惯例,它用于区分字节值8位无符号整数值
  • rune
    • runeint32的别名,在所有方面都等同于int32
    • 按惯例,它用于区分字符值整数值
  • string
    • string是所有8位字节字符串的集合,通常但不一定代表UTF-8编码的文本
    • 字符串可能为空,但是不能为 nil
    • 字符串类型的值是不可变的
  • 由上面得解释我们大概可以明白
    • rune 可以表示得比 byte
    • string 类型的底层是一个byte 数组
    • 以上解释都来此 Go 源码注释
  • 刚刚上面标注了字节字符,现在我们来梳理字符和字节的概念

  • 存储单位 字节

    • 计算机存储信息的最小单位,称之为 bit,二进制的一个01叫一位
    • 计算机存储容量基本单位是字节 Byte,8个二进制位组成 1 个字节
  • 信息表示单位 字符

    • 字符 是一种符号,像 英文a和中文 就是不同字符
    • 不同的字符在不同的编码格式下,所需要的存储单位不一样
    • ASCLII 编码中一个英文字母一字节,一个汉字两字节
    • UTF-8 编码中 一个英文字母一字节,一个常见汉字3字节,不常用的超大字符集汉字4字节

  • Go 源码文件默认采用Unicode字符集,Unicode码点和内存中字节序列的变换实现使用了UTF-8,这使得Go编程无需考虑编码转换的问题非常方便
    • 从编码上来分析
    • byte用来强调一个字节代表的数据(例如字符 a 就是 97),而不是数字;
    • rune用来表示Unicode的码点,即一个字符
    • 通俗一点
    • byte 只能操作简单的字符,不支持中文操作
    • rune 能操作任何字符
  • 代码演示
package main

import "fmt"

func main() {

    str := "hello 世界!"
    fmt.Println(str)
    fmt.Println(len(str))
    fmt.Println(str[1])
    fmt.Println(string(str[1]))
    fmt.Println(str[1:])
    fmt.Println(str[7:])

}
*************************************
输出
hello 世界!
13
101
e
ello 世界!
��界!
  • 会输出 hello 世界!,这证明 GoUTF-8 编码的,输出长度为 13 这说明了一个汉字3字节
  • 输出 ello 世界! 说明 string 底层的数据结构是数组
  • 输出 ��界! 说明 string 底层是一个byte 数组,不然不会乱码
package main

import "fmt"

func StrChangeByRune(str *string, i int, ch rune) {

    temp := []rune(*str)
    temp[i] = ch
    *str = string(temp)
}

func StrChangeByByte(str *string, i int, ch byte) {

    temp := []byte(*str)
    temp[i] = ch
    *str = string(temp)
}

func main() {

    str := "你好 hello"
    str1 := "你好 hello"
    StrChangeByRune(&str, 1, 'A')
    StrChangeByByte(&str1, 1, 'A')
    fmt.Println(str)
    fmt.Println(str1)

}

*******************************
输出
你A hello
�A�好 hello
  • 由输出 你A hello�A�好 hello 可以看出
  • byte 的操作单位是一个字节,可以理解为一个英文字符
  • rune 的操作单位是一个字符,不管这个字符是什么字符
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 1

优秀好文

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!