2016-02-12 103 views
0

我正試圖在Rust中實現一個簡單的REPL計算器,並且我正在遍佈各處的磚牆。Can Rust會消耗一個傳入函數的迭代器嗎?

我在使用硬編碼字符串迭代時消耗字符。當我打一個數字字符時,我想將控制權交給一個函數,該函數將使用該數字的其餘部分(假設該數字具有多個數字)並返回該數字,並將其轉換爲整數。

我在將Chars迭代器傳遞給函數時遇到了問題。我得到的錯誤是use of moved value: 'iter'

我知道我不能改變我給別人的東西 - 東西的所有權已經移動 - 但我不知道其他方式做這件事,特別是因爲Chars迭代器是不可複製的。

#[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)); 
} 

回答

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) 
    ... 
} 

你是接近!

+0

非常感謝你的親切先生! – neektza

+1

順便說一句,你是怎麼知道問題是iter在while循環中超出範圍的?什麼讓它走了?我應該尋找什麼? – neektza

+2

'移動值的使用:'iter'意味着'iter'的所有權被轉移到別的東西上。 Rust中的「移動」意味着「轉讓所有權」。你會習慣的;) –