使用strings.Builder反转字符串时如何正确处理UTF-8多字节字符?
解决Go中字符串反转的多字节字符问题
嗨,我来帮你搞定这个字符串反转的坑!你的代码之所以处理“Hello, 世界”这类包含多字节字符的字符串会乱码,核心原因是Go的string本质是UTF-8编码的字节切片——像中文“世”“界”这类非ASCII字符,每个都占3个字节,你直接用toReverse[i]取单个字节,等于把完整的字符拆成了碎片,反转后自然就变成了乱码。
正确的解决方案
我们需要先把字符串转换成[]rune类型(rune代表Unicode码点,每个元素对应一个完整的字符),然后再反转并构建字符串。同时保留你原本想用的strings.Builder来保证性能,代码如下:
import "strings" func String(toReverse string) string { // 将字符串转为rune切片,确保每个元素是完整的Unicode字符 runes := []rune(toReverse) var reversedString strings.Builder // 预分配容量,避免Builder动态扩容,保持高性能 reversedString.Grow(len(runes)) // 从后往前遍历rune切片,写入每个字符 for i := len(runes) - 1; i >= 0; i-- { reversedString.WriteRune(runes[i]) } return reversedString.String() }
为什么这样可行?
[]rune(toReverse)会把UTF-8字符串解码成对应的Unicode码点集合,每个中文、Emoji或者ASCII字符都会被当作一个独立的元素。- 使用
WriteRune方法写入rune,能保证完整输出每个字符的UTF-8编码,不会出现字节拆分的问题。 - 调用
Grow(len(runes))是个小优化:提前告诉Builder需要容纳多少个rune对应的字节(虽然rune的字节数不固定,但预分配能减少内存拷贝次数)。
测试一下输入“Hello, 世界”,现在会正确输出界世 ,olleH啦!
内容的提问来源于stack exchange,提问作者Cris
相关产品推荐
相关产品推荐

