Я хотел:
for i := 0; i < len(str); i++ {
dosomethingwithrune(str[i]) // takes a rune
}
Но оказывается, что str[i]
имеет тип byte
(uint8
), а не rune
.
Как я могу перебирать строку с помощью рун, а не байтов?
Я хотел:
for i := 0; i < len(str); i++ {
dosomethingwithrune(str[i]) // takes a rune
}
Но оказывается, что str[i]
имеет тип byte
(uint8
), а не rune
.
Как я могу перебирать строку с помощью рун, а не байтов?
См. этот пример из Эффективный переход:
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
Для строк диапазон больше работает для вас, вызывая индивидуальные Unicode кодовые точки, анализируя UTF-8.
Например:
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: 界
Чтобы отразить пример, приведенный в 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
вместо обычного %v
в инструкции Printf
, или мы увидим целочисленное представление кода Unicode (см. Tour of Go).