Я пытаюсь изучить Rust, написав простой лексер. Вот что у меня пока...
use std::fs::File;
use std::io::Read;
use std::str::Chars;
pub struct Lexer<'a> {
file_name: String,
file_contents: String,
iterator: Option<Chars<'a>>,
}
impl<'a> Lexer<'a> {
fn new(fname: &str) -> Lexer {
Lexer {
file_name: fname.to_string(),
file_contents: String::new(),
iterator: None,
}
}
// Reads the file contents and creates iterator
fn init(&'a mut self) {
// Open the file
let mut f = File::open(&self.file_name).expect("Couldn't open file");
// Read the contents
f.read_to_string(&mut self.file_contents).expect("Couldn't read file contents");
self.iterator = Some(self.file_contents.chars());
}
// Gets the next character
fn get_next(&mut self) -> Option<char> {
self.iterator.unwrap().next()
}
}
fn main() {
let mut lexer = Lexer::new("test.txt");
lexer.init();
// Assuming the file "text.txt" contains "Hello World"
// then the following two lines should print "H" then "e"
println!("{}", lexer.get_next().unwrap());
println!("{}", lexer.get_next().unwrap());
}
Однако, когда я пытаюсь скомпилировать его, я получаю следующие две ошибки:
cannot move out of borrowed content [E0507]
main.rs:38 self.iterator.unwrap().next()
и
cannot borrow `lexer` as mutable more than once at a time [E0499]
main.rs:49 println!("{}", lexer.get_next().unwrap());
Google первой ошибки показывает, что Clone()
-ing является возможным решением для такого рода ошибок, но я считаю, что в этом случае это не сработает, поскольку состояние итераторов необходимо обновлять каждый раз, когда вызывается next()
.
Есть ли у кого-нибудь какие-либо предложения о том, как преодолеть эти проблемы и заставить его скомпилировать?