gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 08:35:21 24 4
gpt4 key购买 nike

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

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(){}

编译器提示不能借用*stream一次多次可变。阅读其他 stackoverflow 问题仅回答了为什么会出现此问题,但没有回答如何解决问题。

最佳答案

你的 peek 函数不需要 &mut self,只使用 &self 就可以完全解决你的错误并给你 不能将 *stream 借用为可变的,因为它也被借用为不可变的。无论如何,在不需要时避免 mut 会更好。

您的问题是您将 Token 引用绑定(bind)到 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")),
}
}

或者您可以将 peek 更改为

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

这不会产生借用问题,但会克隆数据。

关于rust - 重构解析器代码以避免借用检查器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44231356/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com