简单来说,rune 是 Go 语言中用来表示“一个字符”的类型

但在计算机里,字符分两种:

  • ASCII 字符:比如英文字母 A、数字 1、符号 @,每个占 1 个字节。

  • Unicode 字符:比如中文 、表情符号 😊,每个可能占 2~4 个字节。

Go 语言中的 rune 就是专门用来处理 Unicode 字符的,它实际上是一个 int32 类型的别名(即 32 位整数,能存下所有 Unicode 编码)。

一:为什么需要 rune?

因为 Go 语言中,字符串底层是字节(byte)数组
如果你直接用 byte 去处理中文字符,会出问题。

看个例子:

package main

import "fmt"

func main() {
    s := "你好"
    fmt.Println(len(s))        // 输出 6(一个中文字符占 3 个字节,UTF-8 编码下)
    fmt.Println(s[0])          // 输出 228(第一个字节,不是 '你' 字)
}

问题len(s) 得到的是字节数,不是字符数
如果想真正按“字符”遍历或操作,就需要 rune

二:什么时候用 rune?

当你需要:

  • 统计字符串里的 字符个数(而不是字节数)

  • 按字符遍历字符串(比如处理中文、表情符号)

  • 截取或修改字符串中的某个字符

就可以用 rune

三 :具体例子

1. 字符串转 rune 切片,获得字符个数

package main

import "fmt"

func main() {
    s := "Hello,世界!😊"
    
    // 转为 rune 切片
    runes := []rune(s)
    
    fmt.Println("字节数:", len(s))        // 输出 22
    fmt.Println("字符数:", len(runes))    // 输出 10
}

2. 按字符遍历字符串(不用 rune 会出错)

package main

import "fmt"

func main() {
    s := "Go语言"

    // 错误方式:按字节遍历,中文会乱
    for i := 0; i < len(s); i++ {
        fmt.Printf("%c ", s[i])   // 输出:G o è ¯ è ¨ € (乱码)
    }

    fmt.Println()

    // 正确方式:用 range 会自动按 rune 遍历
    for _, ch := range s {
        fmt.Printf("%c ", ch)     // 输出:G o 语 言 
    }
}

3. 截取字符串中的某个字符

package main

import "fmt"

func main() {
    s := "abcdefg"
    // 获取第 3 个字符(从 0 开始)
    // 先转成 rune 切片,再取下标
    runes := []rune(s)
    ch := runes[2]
    fmt.Printf("第 3 个字符是:%c\n", ch)  // 输出:c
}

四:总结

类型 含义 占用 适合处理
byte 一个字节(0~255) 1 字节 ASCII 字符(英文字母、数字、符号)
rune 一个 Unicode 字符 4 字节 任何字符(中文、英文、表情等)

一句话

当你处理包含中文、表情等非英文字符时,优先想到 rune,它能保证一个字符就是“一个字符”,不会出现乱码或半个字的情况。

更多推荐