88

我想这样做:

for i := 0; i < len(str); i++ {
    dosomethingwithrune(str[i]) // takes a rune
}

但事实证明,它str[i]具有类型byte( uint8) 而不是rune.

如何通过符文而不是字节来迭代字符串?

4

3 回答 3

135

请参阅Effective Go中的此示例:

for pos, char := range "日本語" {
    fmt.Printf("character %c starts at byte position %d\n", char, pos)
}

这打印:

character 日 starts at byte position 0
character 本 starts at byte position 3
character 語 starts at byte position 6

对于字符串,范围更适合您,通过解析 UTF-8 分解单个 Unicode 代码点。

于 2013-08-08T16:09:12.700 回答
23

为了反映golang.org给出的示例,Go 允许您轻松地将字符串转换为符文片段,然后对其进行迭代,就像您最初想要的那样:

runes := []rune("Hello, 世界")
for i := 0; i < len(runes) ; i++ {
    fmt.Printf("Rune %v is '%c'\n", i, runes[i])
}

当然,我们也可以像这里的其他示例一样使用范围运算符,但这更接近于您的原始语法。无论如何,这将输出:

Rune 0 is 'H'
Rune 1 is 'e'
Rune 2 is 'l'
Rune 3 is 'l'
Rune 4 is 'o'
Rune 5 is ','
Rune 6 is ' '
Rune 7 is '世'
Rune 8 is '界'

请注意,由于rune类型是 的别名int32,因此我们必须在语句中使用%c而不是通常使用,否则我们将看到 Unicode 代码点的整数表示(请参阅Go 之旅)。%vPrintf

于 2017-09-08T12:56:17.740 回答
19

例如:

package main

import "fmt"

func main() {
        for i, rune := range "Hello, 世界" {
                fmt.Printf("%d: %c\n", i, rune)
        }
}

操场


输出:

0: H
1: e
2: l
3: l
4: o
5: ,
6:  
7: 世
10: 界
于 2013-08-08T16:11:51.867 回答