Может ли Rust использовать итератор, переданный в функцию?
Я пытаюсь реализовать простой калькулятор 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));
}
1 ответ
Ответ - да, это сделано в 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)
...
}
Вы были близки!