go中string和rune的区别

149 阅读2分钟

ASCII 和 GBK 的区别

特性ASCIIGBK
字符范围128 个字符(0-127)21,913 个字符
编码长度7 位(1 字节)16 位(2 字节,部分字符可能更多)
支持语言英语简体中文、繁体中文、部分其他语言
设计目标英语字符和基本控制字符中文字符和其他符号
兼容性是 UTF-8 等编码的子集兼容 GB2312,但不兼容 ASCII
使用场景英语环境中文环境

unicode:一种字符集,目的是统一ascll、gbk等编码方式,unicode给所有的字符分配一个编号(也叫码点),例如 A 的码点是 U+0041

utf-8:基于unicode字符集的一种编码方式,例如UTF-8 编码将 U+0041 转换为 1 个字节:0x41

  • 每个 Unicode 字符(码点)会被编码为 1~4 个字节
  • ASCII 字符(0~127)直接使用 1 个字节存储,与 ASCII 编码完全兼容。
  • 非 ASCII 字符(如中文、日文、表情符号等)会占用多个字节。

go中的string

In Go, a string is in effect a read-only slice of bytes.

就是说字符串是一个只读的字节切片

  • 在 Go 中,字符串字面量(如 "Hello, 世界")会被直接存储为 UTF-8 编码的字节序列。
  • 例如,字符串 "世界" 的 UTF-8 编码是 \xE4\xB8\x96\xE7\x95\x8C(对应的 Unicode 码点是 U+4E16U+754C)。

Go 语言中的字符串在内存中默认使用 UTF-8 编码存储。

  1. 兼容性

    • 完全兼容 ASCII,现有的 ASCII 文本无需转换即可直接使用。
  2. 内存高效

    • 对于以 ASCII 为主的文本(如英文),内存占用与 ASCII 相同。
    • 对于多语言混合文本(如中英文混合),比固定长度的 UTF-16/UTF-32 更节省内存。
  3. 灵活性

    • 支持所有 Unicode 字符,包括未来扩展的字符。

go中的rune

go中的rune就是表示一个unicode码点,rune实际上是一个int32类型,因为unicode的一个码点是1~4字节

注意事项

对字符串的直接索引返回的一个字节

str := "世界"
fmt.Println(str[0]) // 输出的是第一个字节(0xe4),不是字符 '世'

若需要按字符处理,需要转换成字符rune[]

runes := []rune(str)
fmt.Println(runes[0]) // 输出 Unicode 码点 19990(即 '世'

string和rune的长度也会不同

fmt.Println(len("世界"))      // 输出 6(字节数)
fmt.Println(len([]rune("世界"))) // 输出 2(字符数)