web-dev-qa-db-fra.com

Comment puis-je parcourir une chaîne par runes dans Go?

Je voulais ceci:

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

Mais il s'avère que str[i] a le type byte (uint8) plutôt que rune.

Comment puis-je parcourir la chaîne en runes plutôt qu'en octets?

32
Matt

Voir cet exemple de Effective Go :

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

Cela imprime:

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

Pour les chaînes, la plage fait plus de travail pour vous, décomposant les points de code Unicode individuels en analysant l'UTF-8.

53
Denys Séguret

Par exemple:

package main

import "fmt"

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

Aire de jeux


Production:

0: H
1: e
2: l
3: l
4: o
5: ,
6:  
7: 世
10: 界
8
zzzz

Pour reproduire un exemple donné à golang.org , Go vous permet de convertir facilement une chaîne en une tranche de runes, puis d'itérer dessus, comme vous le vouliez à l'origine:

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

Bien sûr, nous pourrions également utiliser un opérateur de plage comme dans les autres exemples ici, mais cela suit de plus près votre syntaxe d'origine. Dans tous les cas, cela produira:

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 '界'

Notez que puisque le type rune est un alias pour int32, nous devons utiliser %c au lieu de l'habituel %v dans l'instruction Printf, ou nous verrons la représentation entière du point de code Unicode (voir A Tour of Go ).

3
Justin Kulikauskas