web-dev-qa-db-ja.com

Goでルーン文字列を反復処理するにはどうすればよいですか?

私はこれがしたかった:

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

しかし、str[i]の型はbyteuint8runeではなく。

バイトではなくルーン文字で文字列を反復処理するにはどうすればよいですか?

32
Matt

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コードポイントを分割し、より多くの作業を行います。

53
Denys Séguret

例えば:

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: 界
8
zzzz

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のエイリアスなので、Printfステートメントで通常の%cの代わりに%vを使用する必要があることに注意してください。 Unicodeコードポイントの整数表現が表示されます( A Tour of Go を参照)。

3