Rust会消耗传递给函数的迭代器吗?

时间:2016-02-12 08:25:22

标签: iterator rust move-semantics ownership-semantics

我试图在Rust中实现一个简单的REPL计算器,而且我在整个地方都碰到了砖墙。

我在迭代硬编码字符串时消耗字符。当我点击一个数字字符时,我想将控制权交给一个将消耗其余数字的函数(假设数字有多个数字)并返回数字,转换为整数。

我将Chars迭代器传递给函数时遇到了麻烦。我得到的错误是use of moved value: 'iter'

我明白,我不能改变我给别人的东西 - 有些东西被移动 - 但我不知道其他任何方式这样做,特别是因为Chars迭代器是非-copyable。

#[derive(Clone, Debug)]
enum Token {
    Addition,
    Substraction,
    Multiplication,
    Division,
    Integer(i32),
    Error,
}

fn consume_number(mut iter: std::str::Chars) -> Option<i32> {
    while let Some(item) = iter.next() {
        println!("{:?}", item);
    }

    return Some(1337);
}

fn tokenize(line: &str) -> Vec<Token> {
    let mut iter = line.chars();
    let mut tokens = Vec::new();
    let mut token;

    while let Some(c) = iter.next() {
        if c.is_whitespace() { continue };

        if c.is_digit(10) {
            token = match consume_number(iter) {
                Some(i32) => Token::Integer(i32),
                None => Token::Error,
            };
        } else {
            token = match c {
                '+'                    => Token::Addition,
                '-'                    => Token::Substraction,
                '*'                    => Token::Multiplication,
                '/'                    => Token::Division,
                _                      => Token::Error,
            };
        };
        tokens.push(token);
    }
    return tokens;
}



fn main() {
    let line = "631 * 32 + 212 - 15 / 89";
    println!("{:?}", tokenize(&line));
}

1 个答案:

答案 0 :(得分:3)

答案是肯定的,它是在FromIterator特征中完成的。

您在这里遇到的更为基础:

fn consume_number(mut iter: std::str::Chars) -> Option<i32> { ... }

while let Some(c) = iter.next() {
    ...
    match_consume_number(iter)
    ...
}

调用match_consume_number时,您正在将迭代器的所有权转移给它。这意味着在循环体的下一次迭代中,此iter变量不再可用。

如果迭代器后来仍然可以使用,你应该传递一个引用:

fn consume_number(iter: &mut std::str::Chars) -> Option<i32> { ... }

while let Some(c) = iter.next() {
    ...
    match_consume_number(&mut iter)
    ...
}

你很亲密!