rust - 在一个表达式中两次借用 self 有时会导致错误

标签 rust borrow-checker

以下代码无法编译:

struct Foo {
    values: Vec<i32>,
}

impl Foo {
    fn len(&self) -> usize {
        todo!()
    }
    
    fn set(&mut self) {
        self.values[self.len()] = 0;
    }
}
error[E0502]: cannot borrow `*self` as immutable because it is also borrowed as mutable
  --> src/lib.rs:12:21
   |
12 |         self.values[self.len()] = 0;
   |         ------------^^^^^^^^^^-
   |         |           |
   |         |           immutable borrow occurs here
   |         mutable borrow occurs here
   |         mutable borrow later used here

Playground

有很多方法可以修复此错误,对我来说最令人困惑的是:

    fn set(&mut self) {
        self.set_len(self.len()); // <----- double borrow again?
    }
    
    fn set_len(&mut self, index: usize) {
        self.values[index] = 0;
    }

Playground

为什么第一种情况无法编译,而第二种情况可以编译?在我看来,在这两种情况下 self 在一个表达式中被借用了两次 - 一次是可变的,一次是不可变的。这是否有我看不到的微妙原因,或者是借用检查器的怪癖?

最佳答案

这是借阅检查器的一个怪癖。实现了一个特殊规则来解决“调用可变方法,其中参数是另一个方法的结果”问题。

对于“访问成员并在需要方法结果时对其执行某些操作”没有特殊规则。先借用成员,然后就不能再借用整个对象来调用方法了。

关于rust - 在一个表达式中两次借用 self 有时会导致错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73769846/

相关文章:

stream - 如何在 Rust 中从 futures::stream::wait::Wait 中提取项目?

rust - 如何在 Rust 的可变方法中为结构体字段设置新值并返回旧值

rust - 如何在 Rust/gtk-rs 中创建一个简单的 Gtk MessageDialog?

rust - 请求消息值必须在静态生命周期内有效

rust - 使用现有可变引用的嵌套方法调用

xml - 使用serde序列化结构时,如何展平 `Vec`字段?

rust - 如何在可变借用后打印出一个值?

rust - 在迭代可变成员时访问不可变方法

rust - 有条件地修改 Vec 的可选元素的最惯用的 Rust 方法是什么?

rust - 无法从闭包返回值中移出借用的内容