重构解析器代码以避免借用检查器问题
Refactor parser code to avoid borrow checker issue
重构此解析器代码以避免借用检查器问题的最佳方法是什么?
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
*streamas mutable more than once at a time
的编译器投诉。阅读其他 Whosebug 问题仅回答了为什么会出现此问题,但未回答如何解决问题。
您的 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")),
}
}
或者您可以将 peek 更改为
fn peek(&self) -> Option<Token> {
self.input.get(self.position + 1).cloned()
}
这不会产生借用问题,但会克隆数据。
重构此解析器代码以避免借用检查器问题的最佳方法是什么?
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
*streamas mutable more than once at a time
的编译器投诉。阅读其他 Whosebug 问题仅回答了为什么会出现此问题,但未回答如何解决问题。
您的 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")),
}
}
或者您可以将 peek 更改为
fn peek(&self) -> Option<Token> {
self.input.get(self.position + 1).cloned()
}
这不会产生借用问题,但会克隆数据。