2016-02-12 6 views
0

Я пытаюсь реализовать простой калькулятор REPL в 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' было перенесено на что-то другое. «move» в Rust означает «передать право собственности». Вы привыкнете к этому;) –

Смежные вопросы