重构此解析器代码以避免借用检查程序问题的最佳方法是什么?
pub type Token=u8;
pub trait Stream {
type Item;
fn next(&mut self) -> Option<&Self::Item>;
fn peek(&mut self) -> Option<&Self::Item>;
}
#[derive(Clone)]
pub struct Parser {
input: Vec<Token>,
position: usize,
}
pub type ParseError = String;
pub type ParseResult<T> = Result<T, ParseError>;
impl Stream for Parser {
type Item = Token;
fn next(&mut self) -> Option<&Token> {
let token = self.input.get(self.position);
self.position += 1;
token
}
fn peek(&mut self) -> Option<&Token> {
self.input.get(self.position + 1)
}
}
fn parse_expr(stream: &mut Parser) -> ParseResult<()> {
match stream.peek() { // ~~ borrowed stream here
None => Err(String::from("No more tokens")),
Some(t) => match t {
&0 => parse_number_literal(stream), // ~~ and here
&1 => panic!("parse string"),
&2 => panic!("parse character"),
_ => Err(String::from("Unexpected Token")),
}
}
}
fn parse_number_literal(stream: &mut Parser) -> ParseResult<()> {
let token = stream.next();
Ok(())
}
fn main(){}
关于cannot borrow
* stream as mutable more than once at a time
的编译器投诉。阅读其他stackoverflow问题只能解答为什么会出现这个问题而不是如何解决问题。
答案 0 :(得分:1)
您的peek
功能不需要&mut self
,仅使用&self
即可完全解决您的错误,并为您提供cannot borrow *stream as mutable because it is also borrowed as immutable
。无论如何,在不需要时避免mut
更好。
您的问题是您将Token
引用绑定到t
,因此借用不会结束。您不需要具有多级match
,并且可以使用
fn parse_expr(stream: &mut Parser) -> ParseResult<()> {
match stream.peek() {
None => Err(String::from("No more tokens")),
Some(&0) => parse_number_literal(stream),
Some(&1) => panic!("parse string"),
Some(&2) => panic!("parse character"),
_ => Err(String::from("Unexpected Token")),
}
}
或者你可以改为偷看
fn peek(&self) -> Option<Token> {
self.input.get(self.position + 1).cloned()
}
不会产生借用问题,但会克隆数据。