golang中'range str'和'range [] rune(str)'之间有什么区别吗?

Sha*_*onv 0 go

range str https://play.golang.org/p/I1JCUJnN41h

range [] rune(str) https://play.golang.org/p/rJvyHH6lkl_t

我得到了相同的结果,它们是一样的吗?哪一个更好?

Jim*_*imB 7

您得到相同的结果只是因为您没有包含任何多字节字符,并且忽略了索引。

// ranges over rune as indexed in the string
for i, r := range s {

// ranges over runes as indexed in the []rune
for i, r := range []rune(s)
Run Code Online (Sandbox Code Playgroud)

例如:https : //play.golang.org/p/ZLCc3UNL2dR

s := "???????"

fmt.Println("range s")
for i, r := range s {
    fmt.Printf("%d: %q\n", i, r)
}

fmt.Println("\nrange []rune(s)")
for i, r := range []rune(s) {
    fmt.Printf("%d: %q\n", i, r)
}
Run Code Online (Sandbox Code Playgroud)

哪个打印

range s
0: '?'
3: '?'
6: '?'
9: '?'
12: '?'
15: '?'
18: '?'

range []rune(s)
0: '?'
1: '?'
2: '?'
3: '?'
4: '?'
5: '?'
6: '?
Run Code Online (Sandbox Code Playgroud)


jre*_*ior 6

是,有一点不同.特定

for i, c := range v {
Run Code Online (Sandbox Code Playgroud)

c无论v是字符串还是符文切片都是相同的,但i如果字符串包含多字节字符,则会有所不同.

字符串索引

字符串是字节序列,索引适合于一片字节.除非您有意读取或操作字节而不是代码点或字符,或者确保您的输入不包含多字节字符,否则无论您倾向于索引字符串,都应使用符文切片.

范围循环是特殊的

for i, c := range str {
Run Code Online (Sandbox Code Playgroud)

字符串上的范围循环是特殊的.不是简单地将字符串视为一个字节片段,而是将字符串视为一片字节,range部分像一片符文.

i会的代码点的开始的字节索引.该c会是可以包含多个字节的符文.这意味着i在迭代中可以增加多于一个,因为先前的代码点是多字节字符.

除了Go源代码为UTF-8的公理细节之外,Go实际上只有一种方式特别是对待UTF-8,那就是在字符串上使用for range循环时.我们已经看到了常规for循环会发生什么.相反,对于范围循环,在每次迭代时解码一个UTF-8编码的符文.每次循环时,循环的索引是当前符文的起始位置,以字节为单位,代码点是其值.

在官方Go博客文章中查看更多内容摘自:Go中的字符串,字节,符文和字符