Вопрос: Пропуск вперед n кодовых точек при итерации через строку юникода в Go


В Go, итерация по строке с использованием

for i := 0; i < len(myString); i++{ 
    doSomething(myString[i])
}

только доступ к отдельным байтам в строке, тогда как итерация по строке через

for i, c := range myString{ 
    doSomething(c)
}

итерации по отдельным кодовым точкам Unicode (называемым runes в Go), который может охватывать несколько байтов.

Мой вопрос: как идти вперед, перебирая строку с помощью range Mystring? continue может перейти вперед одним кодовым кодом юникода, но это невозможно сделать i += 3 например, если вы хотите перейти на три кодовых пункта. Итак, каков был бы самый идиоматический способ продвижения вперед n кодовых точек?

я задал этот вопрос  в списке рассылки golang nuts, и на него был дан ответ, любезно предоставленный некоторыми из полезных людей в списке. Кто-то обменял меня, тем не менее, предлагая создать для себя вопрос с ответами на вопрос «Переполнение стека» для этого, чтобы сохранить следующего человека с той же проблемой. Вот что это.


4


источник


Ответы:


Я бы предпочел избежать перехода на []rune, и кодируйте это напрямую.

skip := 0
for _, c := range myString {
    if skip > 0 {
        skip--
        continue
    }
    skip = doSomething(c)
}

Это выглядит неэффективно, чтобы пропускать руны один за другим, как это, но это то же самое количество работы, что и преобразование в []rune было бы. Преимущество этого кода заключается в том, что он избегает выделения среза руны, который будет примерно в 4 раза больше, чем исходная строка (в зависимости от количества больших кодовых точек, которые у вас есть). Конечно, переход на []rune немного проще, поэтому вы можете это предпочесть.


6



Оказывается, это можно сделать довольно просто, выставив строку в кусок рун.

runes := []rune(myString)
for i := 0; i < len(runes); i++{
    jumpHowFarAhead := doSomething(runes[i])
    i += jumpHowFarAhead
}

2