go - golang, £ char 导致奇怪的字符
问题描述
我有一个从一串有效字符生成随机字符串的函数。当它选择一个£时,我偶尔会得到奇怪的结果
我已将其复制到以下最小示例:
func foo() string {
validChars := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~@:!£$%^&*"
var result strings.Builder
for i := 0; i < len(validChars); i++ {
currChar := validChars[i]
result.WriteString(string(currChar))
}
return result.String()
}
我希望这会回来
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~@:!£$%^&*
但它没有,它产生
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~@:!£$%^&*
^
where did you come from ?
如果我从原始的 validChars 字符串中取出 £ 符号,那个奇怪的 A 就会消失。
func foo() string {
validChars := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~@:!$%^&*"
var result strings.Builder
for i := 0; i < len(validChars); i++ {
currChar := validChars[i]
result.WriteString(string(currChar))
}
return result.String()
}
这产生
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~@:!$%^&*
解决方案
Astring
是 的类型别名[]byte
。你对 a 的心智模型string
可能是它由一片字符组成——或者,正如我们在 Go 中所说的那样:一片rune
.
对于validChars
字符串中的许多符文,这很好,因为它们是 ASCII 字符的一部分,因此可以在 UTF-8 中以单个字节表示。但是,£
符文表示为 2 个字节。
现在,如果我们考虑一个字符串£
,它由 1 个符文但 2 个字节组成。正如我所提到的,字符串实际上只是一个[]byte
. 如果我们像您在示例中有效地做的那样抓取第一个元素,我们将只获得表示£
. 当你将它转换回字符串时,它会给你一个意想不到的符文。
解决您的问题的方法是首先将字符串转换validChars
为[]rune
. 然后,您可以按索引访问其各个符文(而不是字节),foo
并将按预期工作。您可以在这个操场上看到它的实际效果。
另请注意,这len(validChars)
将为您提供字符串中的字节数。要获得符文的数量,请utf8.RuneCountInString
改用。
最后,这是 Rob Pike 发表的一篇博文,您可能会觉得有趣。
推荐阅读
- c# - 仅 CSOM SharePoint Search API 筛选器文件
- eclipse - XML 报告中的 JUnit @TestFactory 测试名称
- video-streaming - 在 iOS 和 Mac-Safari 上播放带有冒号的 HLS url 失败
- reactjs - 使用 useState React 钩子并调用其他函数
- sql - 撤销由另一个用户授予权限的用户的权限
- python - tslearn TimeSeriesKMeans 如何计算其指标
- android - 在 Android 上上传到 Google Play 商店后,相机和保存到图库不起作用
- powershell - 如何在会话中设置首选项变量 $progressPreference?
- javafx - 有没有办法在 TextArea 中创建超链接?JavaFX
- javascript - 包含 react-chat-widget 后网站在部署后中断