用问号替换 unwrap() 会导致借用检查器错误

问题描述 投票:0回答:1

我有一个计算器解析器代码设置如下:

struct Parser {
    current_index: usize,
    tokens: Vec<Token>,
}

impl Parser {
    fn new(tokens: Vec<Token>) -> Self {
        Parser {
            current_index: 0,
            tokens: tokens,
        }
    }
    
    fn consume_token(&mut self) {
        self.current_index += 1;
    }

    fn current_token(&self) -> Result<Token, &str> {
        if self.current_index >= self.tokens.len() {
            return Err("Current index out of range");
        }
        Ok(self.tokens[self.current_index])
    }
    
    fn primary(&mut self) -> Result<Expression, &str> {
        let token = self.current_token().unwrap();
        self.consume_token();
        match token {
            Token::Integer(n) => Ok(Expression::Integer(n)),
            Token::OpenParent => {
                let expr = self.expression().unwrap();
                match self.current_token().unwrap() {
                    Token::CloseParent => Ok(expr),
                    _ => Err("syntaxerr"),
                }
            }
            Token::Minus => {
                let expr = self.factor().unwrap();
                Ok(Expression::Unary(
                    Operator::Neg,
                    Box::new(expr),
                ))
            }
            _ => {
                Err("syntaxerr")
            }
        }
    }

    fn factor(&mut self) -> Result<Expression, &str> {
        let expr = self.primary().unwrap();
        let token = self.current_token().unwrap();
        match token {
            Token::Power => {
                self.consume_token();
                let rhs = self.factor().unwrap();
                Ok(Expression::Binary(
                    Operator::Pow,
                    Box::new(expr),
                    Box::new(rhs),
                ))
            }
            _ => {
                Ok(expr)
            }
        }
    }
    ...
}

我想使用 ? 更改错误处理操作员。我以为我可以将 .unwrap 替换为 ?,但这会导致借用检查器错误。

我尝试像这样更改代码:

fn primary(&mut self) -> Result<Expression, &str> {
        let token = self.current_token()?;
        self.consume_token();
        match token {
            Token::Integer(n) => Ok(Expression::Integer(n)),
            Token::OpenParent => {
                let expr = self.expression()?;
                match self.current_token().unwrap() {
                    Token::CloseParent => Ok(expr),
                    _ => Err("syntaxerr"),
                }
            }
            ...
        }
    }

但这会导致编译器错误:无法将

*self
借用为不可变的,因为它也借用为可变的 我已阅读有关 ? 的文档操作员和我不明白为什么在使用时借用检查器的情况会发生变化?而不是 unwrap()。任何帮助将不胜感激。

parsing rust borrow-checker
1个回答
0
投票

reddit 上有人完美回答了我的问题

When you result Result<T, &str>, it infers that the str borrows from &self. Instead, return Result<T, &’static str> so it knows that the str doesn’t borrow from self (or better yet, an enum that can be displayed). 

© www.soinside.com 2019 - 2024. All rights reserved.