【问题标题】:Borrow checker won't let me call getter after calling setter [duplicate]调用setter后,借用检查器不会让我调用getter [重复]
【发布时间】:2020-04-09 12:33:37
【问题描述】:

我一直在研究一个简单的 rust 词法分析器。但是,我遇到了error[E0502]: cannot borrow 'a_rule' as immutable because it is also borrowed as mutable 问题。我检查了其他答案,但似乎找不到原因。

pub struct Rule<'a> {
    selector: &'a str,
}

impl<'a> Rule<'a> {
    pub fn new(selector: &'a str) -> Self {
        Self {
            selector
        }
    }

    pub fn get_selector(&'a self) -> &'a str {
        self.selector
    }

    pub fn set_selector(&'a mut self, selector: &'a str) {
        self.selector = selector
    }
}

#[cfg(test)]
mod tests {
    use super::Rule;

    #[test]
    fn set_selector_test() {
        let mut a_rule = Rule::new(".foo");
        a_rule.set_selector(".bar");

        assert_eq!(a_rule.get_selector(), ".bar")
    }
}

错误:

error[E0502]: cannot borrow `a_rule` as immutable because it is also borrowed as mutable
  --> src/lib.rs:30:20
   |
28 |         a_rule.set_selector(".bar");
   |         ------ mutable borrow occurs here
29 | 
30 |         assert_eq!(a_rule.get_selector(), ".bar")
   |                    ^^^^^^
   |                    |
   |                    immutable borrow occurs here
   |                    mutable borrow later used here

(Playground)

我还想借此机会询问是否建议使用 java 之类的 get 和 set 方法,或者只是将结构中的成员设置为 public。

请随时指出任何其他愚蠢的错误。

【问题讨论】:

标签: rust immutability


【解决方案1】:

通过使get_selectorset_selector 采用&amp;'a self/&amp;'a mut self,您已将规则的生命周期与字符串的生命周期联系起来,但这不是它们之间的正确关系。你可以产生&amp;'a strs,而不需要你的self来活那么久(或者被可变地借用那么久),因为self.selector已经是一个&amp;'a str

删除self 引用上的'a

pub fn get_selector(&self) -> &'a str {
    self.selector
}

pub fn set_selector(&mut self, selector: &'a str) {
    self.selector = selector;
}

(但你需要这个 getter 和 setter 吗?考虑不变性!)

【讨论】:

  • 虽然整个生命周期看起来很奇怪,但从逻辑上讲,setter 应该采用一个比 self 寿命更长的 str,而 getter 应该返回一个从 self 借来的 str。在我看来,这只适用于'static,此时您最好将其输入为'static no?
  • @Masklinn &amp;str 不一定是'static,它只需要(至少)与'a 一样长——这就是拥有生命周期注释的全部意义,不?如果引用必须是'static,则根本不需要注释Rule
  • 谁能解释编译器的借用错误和生命周期之间的关系?当你已经有了一个可变借用时,编译器似乎在抱怨有一个不可变借用。但解决办法是改变生命周期......
  • @drootang 生命周期注释是告诉编译器借用应该持续多长时间的方式。使可变借用持续更长时间,即使其寿命超过'a,导致它与不可变借用重叠。删除该约束允许编译器使借用更短并且不再重叠。
  • @trentcl 在技术上是可以的,但实际上因为它将引用存储在结构中,所以您使用非'static 字符串编写任何有用代码的可能性非常低。
猜你喜欢
  • 1970-01-01
  • 2022-08-20
  • 1970-01-01
  • 2019-02-27
  • 2012-02-25
  • 2023-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多