借用 Rust

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

我对 Rust 相当陌生。因此我对借用检查器等没有这么深入的理解。我已经用 C++ 做了一个编译器,所以我尝试在 Rust 中做同样的事情,因为这似乎是一个学习它的好机会。

我已经完成了我的词法分析器,它工作得非常好,而且我对 Rust 总体上也很满意。但借用检查器和生命周期有时会让我失望。当我想创建我的解析器时,我遇到了一个让我相当沮丧的问题。为了给出我的实现的简化结构,我有以下代码:

#[derive(PartialEq)]
enum TokenKind {
    Test,
}

struct Token<'a> {
    source: &'a str,
    kind: TokenKind,
}

struct Parser<'a> {
    tokens: &'a [Token<'a>],
    position: usize,
}

impl<'a> Parser<'a> {
    fn matches(&mut self, kinds: &[TokenKind]) -> Option<&Token> { // rustc: let's call the lifetime of this reference `'1` 
        let current = match self.current() { // rustc: `self.position` is borrowed here 
            Some(current) if kinds.contains(&current.kind) => current,
            _ => return None,
        };

        self.position += 1; // rustc: cannot assign to `self.position` because it is borrowed `self.position` is assigned to here but it was already borrowed 
        Some(current) // rustc: returning this value requires that `*self` is borrowed for `'1` 
    }

    fn current(&self) -> Option<&Token> {
        self.tokens.get(self.position)
    }
}

现在我的问题是如何修复此代码?为什么“self.position”已经被“self.current”方法借用了?也许这是一个我不确定的根本问题。

尽管我阅读了借用检查和生命周期的文档,但我不太确定如何解决这个问题。因此,我会很高兴获得一些帮助,即使它只是解决这个确切问题的资源。

rust lifetime borrow-checker
1个回答
1
投票

现在我的问题是如何修复此代码?为什么“self.position”已经被“self.current”方法借用了?也许这是一个我不确定的根本问题。

虽然 rust 可以在程序上内部分割借用,但它不能在程序上这样做。

current
是一个
&Token
,但因为它是调用
Parser::current
的结果,所以它与借用 整个 self 相关联。因此,只要该问题尚未解决,您就无法更新
self
的任何成员。

解决方案是仅内联

current
,这样拆分借用是过程内的,并且编译器可以理解发生了什么。

另一种方法是删除

position
并使
tokens
成为(可查看的)迭代器。或者使其成为不可查看的迭代器,但让
match
处理“当前令牌”,这是从迭代器获得的最后一个令牌(基本上是相同的结果)。

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