在 Go 语言中,string() 是一种 类型转换,它的行为取决于你转换的是什么类型。它不是函数,而是内建的类型转换语法。
下面我把所有常见用法一次讲清楚,你就不会再困惑了。
1.string([]byte)
把 字节数组 转成 UTF-8 字符串。
bs := []byte{65, 66, 67} // ASCII A B C
s := string(bs)
fmt.Println(s) // ABC
如果 byte 是 UTF-8 字节,能正常转换;否则会乱码。
2.string([]rune)
把 rune 数组 转成字符串。
rune 是 Unicode 码点(int32),转换时 Go 会自动编码成 UTF-8。
rs := []rune{'你', '好'}
s := string(rs)
fmt.Println(s) // 你好
这是处理中文最安全的方式。
3.string(int)
把一个整数当成 Unicode 码点转换成一个字符。
s := string(97)
fmt.Println(s) // a (97 = 'a')
若整数不是有效 Unicode,会出现 �(替换符)。
❗4.string([]int)—— 不允许
不可以:
string([]int{65, 66})
会报错,由于必须是 []byte 或 []rune。
❗5.string(map / struct / other)—— 不允许
string() 的合法类型超级有限,不是万能转换。
总结(提议收藏)
|
输入类型 |
行为 |
|
[]byte |
每个 byte 按 UTF-8 解码成字符 |
|
[]rune |
每个 rune 编码为 UTF-8 字符 |
|
int |
整数作为 Unicode 码点转成字符 |
|
其他类型 |
❌ 不允许转换 |
下面我用最清晰、最底层的方式解释:
✅ 为什么string([]rune)可以安全处理中文?
由于 rune 是 Unicode 码点,而中文字符在 Unicode 中都对应一个唯一的码点,所以从 rune → string 时,Go 会自动把 每个 rune 按 UTF-8 正确编码。
1️⃣rune是什么?
在 Go 里:
type rune = int32
它代表一个 Unicode 码点(0~0x10FFFF)。
例如:
|
字符 |
Unicode 码点 |
rune 值 |
|
你 |
U+4F60 |
0x4F60(20320) |
|
好 |
U+597D |
0x597D(22909) |
当你写:
[]rune("你好")
你得到的是:
[20320, 22909]
每个 rune 表明一个完整的字符。
2️⃣ 当你执行string([]rune)时 Go 做了什么?
Go 遇到 string(rs)(rs 是 []rune),会:
- 遍历每个 rune
- 将 rune 按标准的 UTF-8 规则编码成 1~4 字节
- 拼成新的 string
例:
rune '你' (U+4F60) → UTF-8:E4 BD A0(3 个字节)
rune '好' (U+597D) → UTF-8:E5 A5 BD(3 个字节)
最终 string 是:
E4 BD A0 E5 A5 BD helloworld
⚠️ 注意:
string 中存的是 UTF-8 字节,而不是 rune。
3️⃣ 为什么这样做是“安全”的?
✔ 安全点 1:不会破坏 UTF-8
UTF-8 是变长编码:
- 英文:1 字节
- 中文:3 字节
- emoji:4 字节
如果你直接改 []byte:
bs := []byte("你")
bs[0] = 'A'
你只改了其中一个字节,会造成破坏 UTF-8 编码 → 乱码
(由于中文是 3 字节编码,不能只改一个)
但 rune 是独立的 32 位整数,不涉及 UTF-8 字节结构,所以修改不会破坏编码。
✔ 安全点 2:一个 rune 就是一个“完整字符”
中文字符不会被拆开。
如果用 []byte:
'你' = 3 字节
列如更改删除时容易破坏字节结构
如果用 []rune:
'你' = 一个 rune
超级适合:
- 修改某个中文字符
- 删除一个字符
- 截取 N 个字符(不是字节)
- Unicode 安全处理
✔ 安全点 3:Go 在转换时保证 UTF-8 编码合法性
只要 rune 是合法 Unicode(大部分情况是)
Go 转 string 时必定是合法 UTF-8,不会出现乱码。
4️⃣ 示例:为什么 byte 会出问题?
str := "你好"
bs := []byte(str)
bs[0] = 'A'
fmt.Println(string(bs))
UTF-8 被破坏后,输出:
A�好
而用 rune:
rs := []rune(str)
rs[0] = '我'
fmt.Println(string(rs))
输出正常:
我好
结论
string([]rune) 之所以安全处理中文,由于:
- rune 是完整的 Unicode 码点(不会被拆成字节)
- 转换字符串时 Go 会自动用 UTF-8 正确编码
- 不会破坏 UTF-8 字节结构
- 适用于任何 Unicode 字符(包括 emoji)

















暂无评论内容