range str https://play.golang.org/p/I1JCUJnN41h
range [] rune(str) https://play.golang.org/p/rJvyHH6lkl_t
我得到了相同的结果,它们是一样的吗?哪一个更好?
您得到相同的结果只是因为您没有包含任何多字节字符,并且忽略了索引。
// 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)
是,有一点不同.特定
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中的字符串,字节,符文和字符