我有一个函数,它从一个有效字符字符串中生成一个随机字符串。当它选择一个£时,我偶尔会得到一些奇怪的结果
我将其复制到以下最小示例:
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 ?如果我把if标志从原来的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~@:!$%^&*
发布于 2021-07-23 11:13:33
string是[]byte的类型别名。string的心理模型可能是由一段字符组成--或者,我们称之为Go:rune的一个片段。
对于您的validChars字符串中的许多代码来说,这是很好的,因为它们是ASCII字符的一部分,因此可以用UTF-8中的单个字节表示。但是,£符文表示为2个字节。
现在,如果我们考虑一个字符串£,它包含1个符文,但2个字节。正如我所提到的,字符串实际上只是一个[]byte。如果我们获取第一个元素,就像您在示例中所做的那样,我们将只获得表示£的两个字节中的第一个。当你把它转换回字符串时,它会给你一个意想不到的符文。
解决问题的方法是首先将字符串validChars转换为[]rune。然后,您可以按索引访问它的单个文本(而不是字节),foo将按预期工作。您可以在这个操场中看到它的作用。
还请注意,len(validChars)将给出字符串中字节的计数。要获得符文的计数,请使用utf8.RuneCountInString代替。
最后,这里是来自Rob的一篇关于这个主题的博客文章,你可能会觉得很有趣。
https://stackoverflow.com/questions/68498123
复制相似问题