最稳妥的做法是先将字符串转为[]rune,再用双指针原地交换;因Go中string只读且UTF-8编码,直接操作[]byte会导致中文或emoji乱码,而for循环双指针交换兼顾Unicode正确性与性能。

直接用 for 循环双指针交换最稳妥
Go 没有内置字符串反转函数,strings 包里也找不到 Reverse。别被网上某些“一行切片反转”的写法误导——那只是对 []rune 或 []byte 的操作,不是对 string 本身。字符串在 Go 中是只读的,必须转成可变切片再处理。
常见错误是直接对 []byte 反转:遇到中文或 emoji 就乱码,因为 UTF-8 编码下多字节字符被拆开交换了。
- 正确做法:先转
[]rune,再用双指针原地交换 - 别用
for i := len(runes)-1; i >= 0; i--拼接,性能差且分配多次内存 - 如果确定字符串只含 ASCII 字符(比如纯数字、英文),可以用
[]byte,速度快但不通用
func reverseString(s string) string 的标准实现
这是最常用、最安全的写法,兼顾 Unicode 正确性和可读性:
func reverseString(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)
}注意点:
立即学习“go语言免费学习笔记(深入)”;
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
i 是循环条件,不是 <code>i ,否则中间字符会被自己交换一次(没影响但多余)- 别漏掉
string(runes)转回,Go 不允许直接返回[]rune给string类型变量 - 这个函数没有副作用,输入字符串不会被修改(本来也不能改)
性能敏感时怎么选?[]byte 还是 []rune?
实测 10KB 纯 ASCII 字符串,[]byte 版本比 []rune 快约 2.3 倍;但只要含一个中文,[]byte 版本就输出乱码,毫无意义。
- 99% 场景用
[]rune—— 安全第一,性能差异在绝大多数业务里感知不到 - 只有在明确约束输入为 ASCII(比如 base64、hex、纯数字 ID),且每秒调用数万次以上,才值得单独写
[]byte版本 - 别试图用
unsafe绕过转换——得不偿失,还破坏可维护性
为什么不能用 strings.Builder 从后往前 WriteRune?
可以,但没必要。有人图省事这么写:
b := strings.Builder{}
runes := []rune(s)
for i := len(runes)-1; i >= 0; i-- {
b.WriteRune(runes[i])
}
return b.String()问题在于:
- 多分配一次
[]rune内存,又多一次WriteRune的内部判断和追加逻辑 - 不如双指针原地交换简洁,也不如直接
string(runes)直观 -
strings.Builder适合拼接多个字符串,单字符串反转是杀鸡用牛刀
Unicode 处理的边界情况多,简单问题就用简单解法。别为了“看起来高级”去套复杂工具。

















