Go语言 当使用range迭代字符串时,range返回的值和直接使用索引访问rune的值之间的类型不同,为什么?

z9ju0rcb  于 2023-06-19  发布在  Go
关注(0)|答案(1)|浏览(139)

当我遍历一个字符串来访问符文时,我有两个选择:

s := "AB"
range i, v := range s {
    // access the copy of the rune via value
    fmt.Printf("%T", v) // prints int32
    // access the rune via its index directly trough s
    fmt.Printf("%T", s[i]) // prints uint8
}

我知道int32是rune类型,而uint8是字节类型。这意味着一次我得到一个符文,另一次我得到一个字节。但为什么呢?
有关上下文:在这种情况下,这不是问题,因为ASCII字符在uint8中有足够的空间,但是当有一个Emoji时,例如,空间不够,因此值是错误的。

aiqt4smr

aiqt4smr1#

因为它们是不同的东西做不同的事情。字符串上的范围遍历符文,对字符串的索引访问访问字节,因为字符串存储为UTF-8,并且不具有对中间给定符文的恒定时间访问。要明确的是:s[1] * 不是 * s的第二个符文、代码点或字符;是第二个字节。
如果你想遍历字节,你可以使用range([]byte(s))。如果你想随机访问符文,你可以使用[]rune(s)(最好转换一次并多次索引它,否则你可能最终会意外地二次),或者找出如何根据strings包中的函数来做你想做的事情。

相关问题