Могу ли я использовать itertools :: PutBack :: put_back в цикле? - PullRequest
1 голос
/ 15 мая 2019

Мой вариант использования:

  • Зацикливание строки
  • Реагирование на каждый символ в конечном автомате лексического анализатора
  • При просмотре некоторых символов следует понимать, что предыдущийсимвол был концом его токена
  • завершает переход токена
  • обратно в состояние Empty (что означает, что токен не создан частично)
  • push«дополнительный» символ возвращается на итератор с помощью put_back
  • , чтобы продолжить обработку конечного автомата, где символ возврата будет доступен для первого символа в следующем токене.

Вот пример попытки:

use itertools::put_back; // 0.8.0

fn main() {
    let hello = "Hello world".to_owned();
    let hello_iter = hello.chars();
    let mut putback_iterator = put_back(hello_iter);
    let mut already_putback = false;
    for c in putback_iterator {
        if c == 'd' && !already_putback {
            putback_iterator.put_back('!');
            already_putback = true;
        }
        println!("Char is {}", c.to_string());
    }
}

Сообщение об ошибке:

error[E0382]: borrow of moved value: `putback_iterator`
  --> src/main.rs:10:13
   |
6  |     let mut putback_iterator = put_back(hello_iter);
   |         -------------------- move occurs because `putback_iterator` has type `itertools::adaptors::PutBack<std::str::Chars<'_>>`, which does not implement the `Copy` trait
7  |     let mut already_putback = false;
8  |     for c in putback_iterator {
   |              ---------------- value moved here
9  |         if c == 'd' && !already_putback {
10 |             putback_iterator.put_back('!');
   |             ^^^^^^^^^^^^^^^^ value borrowed here after move

Как бы я перебрал символы и выполнил put_back?Я не могу найти работающие примеры, используя put_back.

1 Ответ

1 голос
/ 16 мая 2019
Циклы

for позволяют перебирать все, что реализует IntoIterator. Эта черта определяет into_iter(self), которая потребляет объект, к которому она вызывается, и возвращает итератор. Это верно даже тогда, когда self уже является итератором (как в вашем коде).

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

В качестве альтернативы можно использовать цикл while let:

use itertools::put_back; // 0.8.0

fn main() {
    let hello = "Hello world".to_owned();
    let hello_iter = hello.chars();
    let mut putback_iterator = put_back(hello_iter);
    let mut already_putback = false;
    while let Some(c) = putback_iterator.next() {
        if c == 'd' && !already_putback {
            putback_iterator.put_back('!');
            already_putback = true;
        }
        println!("Char is {}", c.to_string());
    }
}

Playground Link

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...