Каков наиболее простой способ написания итераторов, которые отображают неопределенное количество входных элементов на другие объекты в Rust?

#rust

#Ржавчина

Вопрос:

Я пытаюсь реализовать лексер. Поскольку лексеры выделяют токены, я полагаю, что мы можем воспринимать лексер как специальный итератор, который сопоставляет определенные фрагменты char s с Token s . Поэтому я ожидаю Lexer сохранить Iterator<Item=char> и манипулировать этим итератором вместо a amp;str , чтобы обеспечить максимальную гибкость.

 struct Lexer<T: Iterator<Item=char>> {
    source: T
}
 

Тем не менее, мне трудно манипулировать итератором, поскольку почти все адаптеры итераторов берут на себя ответственность, а с дженериками я не могу изменить тип T во время выполнения, если не переключусь на Box .

 self.source.take_while(|x| x.is_whitespace())
 

Возможный обходной путь — потребовать, чтобы итератор реализовывал Clone , использовал клон каждый раз, когда я хочу его преобразовать, запоминал, сколько символов я видел, и вызывал next это много раз. Я считаю, что это слишком неуклюже.

Интересно, существует ли простой способ написания итераторов, которые сопоставляют неопределенное количество входных элементов (в данном случае, char элементов) с другим объектом (в данном случае, Token объектами)?

Самый элегантный способ, который я могу придумать до сих пор, — это использовать while let etc. которые не так похожи на fluent-style. Я проверил реализацию GroupBy in itertools и обнаружил, что они тоже используют этот while let подход.

Комментарии:

1.Вы можете использовать .by_ref() , чтобы не брать на себя ответственность за цепочки итераторов. например, игровая self.source.by_ref().take_while(|x| x.is_whitespace()) площадка

2. @kmdreko Спасибо! Я не знал, что итераторы также могут владеть изменяемыми ссылками. Теперь я знаю, как использовать (amp;mut iter) .

3. Рад, что я смог помочь, это решает все ваши проблемы? Я не могу сказать, все ли это, что вам нужно, или у вас все еще есть проблемы с чем-то

4. @kmdreko Пока я не нашел никаких ошибок при его использовании. Еще раз спасибо! Я некоторое время балансировал ссылки при использовании итераторов, никогда не думал о добавлении одного самостоятельно 🙂