🧠 一句话理解
rune
是 Go 语言中的 字符类型,本质上是int32
,用于表示一个 Unicode 码点(code point)。
🧩 为什么需要 rune
?
Go 的 string
是 UTF-8 字节序列,而一个中文、emoji 可能是多个字节,用 byte
处理容易出错。
✅ 所以:用 rune
表示单个字符更安全、统一!
🧪 基本定义与使用
var r rune = '你' fmt.Println(r) // 输出 Unicode 编码:20320 fmt.Printf("%c\n", r) // 输出字符:你
✅ 说明:
-
'你'
是字符字面量(用单引号) -
r
的类型是rune
,也就是int32
-
%c
用于格式化输出字符
🧮 rune
与 Unicode 的关系
fmt.Printf("%c -> %U\n", 'A', 'A') // A -> U+0041 fmt.Printf("%c -> %U\n", '你', '你') // 你 -> U+4F60
rune
就是 Unicode 编码点,比如:
字符 | Unicode 编码 | rune 值(十进制) |
---|---|---|
A | U+0041 | 65 |
你 | U+4F60 | 20320 |
🌟 | U+1F31F | 127775 |
📚 遍历字符串中的 rune
s := "你好,Go!" for i, r := range s { fmt.Printf("第 %d 个字符:%c (Unicode: %U)\n", i, r, r) }
✅ for...range
会自动把 string
拆成 rune
单位,而不是 byte!
⚔️ 和 byte
的对比(重点)
特性 | byte | rune |
---|---|---|
本质类型 | uint8(1 字节) | int32(4 字节) |
用于表示 | ASCII/单字节字符 | Unicode 字符(多字节) |
示例字符 | 'A' (一个字节) | '你' (三个字节) |
用途 | 处理英文、底层IO更快 | 处理中文、emoji安全 |
🧪 字符串转换为 rune
切片
str := "你好Go" runes := []rune(str) fmt.Println(len(str)) // 字节数(UTF-8):6 fmt.Println(len(runes)) // 字符数(rune):3 fmt.Println(string(runes)) // 还能转回字符串
🧙♂️ rune 的实战应用场景
-
✅ 字符统计(处理中文、emoji 不出错)
-
✅ 字符串反转(不能直接对 byte 做反转)
-
✅ 正确截取字符串中的“字符”
-
✅ 自定义解码器或语法分析器(处理 code point)
🔁 字符串反转示例(用 rune 才对)
func reverse(s string) string { runes := []rune(s) for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 { runes[i], runes[j] = runes[j], runes[i] } return string(runes) } fmt.Println(reverse("你好Go!")) // !oG好你
❓ FAQ:常见问题
❓ '你'
是字符串还是字符?
答:是字符常量,Go 中用单引号表示字符,类型为 rune
。
❓ rune
和 int32
是一回事?
答:是的,rune
是 int32
的别名,用于语义更清晰,表示“字符”。
❓ 中文字符占多少字节?
答:UTF-8 下:1个中文字符占 3个字节,但在 Go 中用 1 个 rune
表示(int32)。
📦 总结一句话
在处理多语言字符时,不要用 byte 用 rune,否则你会掉进中文乱码的坑!