【问题标题】:How do I reduce scope of mutable [duplicate]如何减少可变范围[重复]
【发布时间】:2020-05-15 11:09:18
【问题描述】:

我有一个元素向量,我遍历并检查某些属性(不可变)。在某些情况下,我会对该向量中的单个项目执行可变操作,然后更新容器。我该怎么做?

struct A {
    buffer: Vec<B>,
}

impl A {
    fn update(&self) {}
}

struct B {}

impl B {
    fn check(&self) -> bool { true }
    fn do_stuff(&mut self) {}
}

fn main() {
    let mut a = A { buffer: vec![B{}] };

    for b in a.buffer.iter_mut() { // mutable borrow occurs here
        if b.check() {
            b.do_stuff();
            a.update();  // imutable borrow occurs here
        }
    }
}

或者,如果我选择不可变的iter()。是否有可能在do_stuff 的范围内使其可变?

【问题讨论】:

  • 更新方法是作用于buffer还是作用于其他一些字段?
  • IMO,到目前为止,最简单的方法是按索引迭代容器。不是很漂亮,但很有效。
  • @rolisz。 imutalbe 在缓冲区
  • @rodrigo。是的,你是对的。不过,我一直在寻找更土气的东西。让我们看看

标签: rust immutability borrowing


【解决方案1】:

请注意,根据您的用例,编译器实际上可能会阻止您出现错误。这是“借用检查器妨碍”还是“借用检查器将您从错误中拯救出来”的情况,很大程度上取决于您在 update 方法中实际计划执行的操作。

使用其当前签名,此方法可以对Vec 执行任意数量的操作,这可能会触发其重新分配。或者甚至将整个Vec 换成不同的。两者都肯定会使您在缓冲区上的迭代器无效。

值得称赞的是,您尽量避免使用索引。如果您在这里遇到逻辑错误,您要做的就是将编译时错误换成运行时错误(可能是越界访问),这可能更难找到或调试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 2014-07-16
    • 2018-11-14
    • 2015-11-01
    • 2016-09-14
    • 2010-12-07
    相关资源
    最近更新 更多