Rust 重构解析器代码以避免借用检查器问题

Rust 重构解析器代码以避免借用检查器问题,rust,borrow-checker,Rust,Borrow Checker,重构此解析器代码以避免借用检查器问题的最佳方法是什么 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 {

重构此解析器代码以避免借用检查器问题的最佳方法是什么

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(){}
pub-type-Token=u8;
酒吧特征流{
类型项目;
fn next(&mut self)->选项;
fn peek(&mut self)->选项;
}
#[衍生(克隆)]
发布结构分析器{
输入:Vec,
位置:usize,
}
发布类型ParseError=字符串;
发布类型ParseResult=Result;
解析器的impl流{
类型项=令牌;
fn下一步(&mut self)->选项{
让token=self.input.get(self.position);
自身位置+=1;
代币
}
fn peek(&mut self)->选项{
self.input.get(self.position+1)
}
}
fn parse_expr(流:&mut Parser)->ParseResult{
匹配stream.peek(){/~~这里是借用的流
None=>Err(字符串::from(“无更多令牌”),
一些(t)=>匹配t{
&0=>parse_number_literal(流),//~~这里
&1=>panic!(“解析字符串”),
&2=>panic!(“解析字符”),
_=>Err(字符串::from(“意外标记”)),
}
}
}
fn parse_number_literal(流:&mut Parser)->ParseResult{
让token=stream.next();
好(())
}
fn main(){}

编译器抱怨
不能借用
*流
,因为它一次可以多次修改
。阅读其他stackoverflow问题只回答了出现此问题的原因,而没有回答如何解决问题。

您的
peek
函数不需要
&mut self
,只使用一个
&self
将完全解决您的错误,并使您
无法借用*流作为可变流,因为它也是作为不可变流借用的。无论如何,在不需要时避免mut是更好的选择

您的问题是您将该
令牌
引用绑定到
t
,因此借用不会结束。您不需要进行多级
匹配
,也可以对

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 parse_expr(流:&mut Parser)->ParseResult{
匹配stream.peek(){
None=>Err(字符串::from(“无更多令牌”),
Some(&0)=>parse_number_literal(流),
Some(&1)=>panic!(“解析字符串”),
Some(&2)=>panic!(“解析字符”),
_=>Err(字符串::from(“意外标记”)),
}
}
或者你可以把peek改成

fn peek(&self) -> Option<Token> {
    self.input.get(self.position + 1).cloned()
}
fn peek(&self)->选项{
self.input.get(self.position+1.cloned())
}

这不会创建借阅问题,但会克隆数据。

谢谢。将代码重构为只有一个匹配项会有所帮助。