我可以在循环中使用itertools :: PutBack :: put_back吗?

时间:2019-05-15 20:03:12

标签: rust itertools borrow-checker

我的用例:

  • 环绕字符串
  • 对词法分析器状态机中的每个字符进行反应
  • 看到一些字符后,意识到上一个字符是其令牌的结尾
  • 整理令牌
  • 转换回 Empty 状态(表示没有部分构造令牌)
  • 使用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 个答案:

答案 0 :(得分:1)

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