Не забудьте преобразовать свой string в фрагмент руны: см. "Slice разбить на буквы".
for
автоматически преобразует string
в rune
, поэтому в этом случае нет необходимости в дополнительном коде, чтобы сначала преобразовать string
в rune
.
for i, r := range s {
fmt.Printf("i%d r %c\n", i, r)
// every 3 i, do something
}
r[n:n+3]
будет лучше всего работать с кусочком руны.
Индекс будет увеличиваться на единицу для каждой руны, в то время как он может увеличиваться более чем на единицу для каждого байта в кусок строки: "世界": i
будет равно 0 и 3: символ (руна) может состоять из нескольких байтов.
Например, рассмотрим s := "世a界世bcd界efg世"
: 12 рун. (см. play.golang.org)
Если вы попытаетесь разобрать его байт за байтом, вы пропустите (в наивном разделении каждые 3 символа реализации) некоторые из «индексов по модулю 3» (равны 2, 5, 8 и 11), потому что индекс будет увеличиваться за эти ценности:
for i, r := range s {
res = res + string(r)
fmt.Printf("i %d r %c\n", i, r)
if i > 0 && (i+1)%3 == 0 {
fmt.Printf("=>(%d) '%v'\n", i, res)
res = ""
}
}
Выход:
i 0 r 世
i 3 r a <== miss i==2
i 4 r 界
i 7 r 世 <== miss i==5
i 10 r b <== miss i==8
i 11 r c ===============> would print '世a界世bc', not exactly '3 chars'!
i 12 r d
i 13 r 界
i 16 r e <== miss i==14
i 17 r f ===============> would print 'd界ef'
i 18 r g
i 19 r 世 <== miss the rest of the string
Но если бы вы повторяли руны (a := []rune(s)
), вы бы получили то, что ожидали, поскольку индекс будет увеличиваться на одну руну за раз, что упрощает агрегирование ровно 3 символов:
for i, r := range a {
res = res + string(r)
fmt.Printf("i%d r %c\n", i, r)
if i > 0 && (i+1)%3 == 0 {
fmt.Printf("=>(%d) '%v'\n", i, res)
res = ""
}
}
Выход:
i 0 r 世
i 1 r a
i 2 r 界 ===============> would print '世a界'
i 3 r 世
i 4 r b
i 5 r c ===============> would print '世bc'
i 6 r d
i 7 r 界
i 8 r e ===============> would print 'd界e'
i 9 r f
i10 r g
i11 r 世 ===============> would print 'fg世'
person
VonC
schedule
05.09.2014
s[n:n+3]+"\n"
? - person Volker   schedule 05.09.2014