【问题标题】:Immutable reference after mutable borrow可变借用后的不可变引用
【发布时间】:2015-06-17 03:56:22
【问题描述】:

我每次使用 Rust 时都会遇到与所有权/借用相关的类似问题,所以这里有一段最简单的代码来说明我的常见问题:

use std::cell::RefCell;

struct Res {
    name: String,
}

impl Res {
    fn new(name: &str) -> Res {
        Res {
            name: name.to_string(),
        }
    }

    // I don't need all_res to be mutable
    fn normalize(&mut self, all_res: &Vec<Res>) {
        // [...] Iterate through all_res and update self.name
        self.name = "foo".to_string();
    }
}

fn main() {
    let res = RefCell::new(vec![Res::new("res1"), Res::new("res2")]);

    for r in res.borrow_mut().iter_mut() {
        // This panics at runtime saying it's
        // already borrowed (which makes sense, I guess).
        r.normalize(&*res.borrow());
    }
}

在阅读了RefCell 之后,我认为这会起作用。它编译,但在运行时恐慌。

如何在迭代同一个向量时引用一个向量?有没有更好的数据结构可以让我这样做?

【问题讨论】:

    标签: rust


    【解决方案1】:

    您的程序出现恐慌,因为您试图同时可变地和不可变地借用 Vec:这是不允许的。

    您需要做的只是将Strings 包装在RefCell 中。这允许您在迭代 Vec 时改变字符串。

    use std::cell::RefCell;
    
    struct Res {
        name: RefCell<String>,
    }
    
    impl Res {
        fn new(name: &str) -> Res {
            Res {
                name: RefCell::new(name.to_string()),
            }
        }
    
        // I don't need all_res to be mutable
        fn normalize(&self, all_res: &Vec<Res>) {
            // [...] Iterate through all_res and update self.name
            *self.name.borrow_mut() = "foo".to_string();
        }
    }
    
    fn main() {
        let res = vec![Res::new("res1"), Res::new("res2")];
    
        for r in res.iter() {
            r.normalize(&res);
        }
    
        println!("{}", *res[0].name.borrow());
    }
    

    【讨论】:

    • 感谢您的帮助 - 我仍然对 Rust 所有权规则感到迷茫。我想我会尝试开发一个简单的标记和清除垃圾收集器来实践这些规则。
    • @user3696012:我想我会尝试开发一个简单的标记和清除垃圾收集器来实践这些规则。 => 尽量避免打开unsafe孵化,当您了解所有权规则时,这已经够难了,但是如果您还没有将它们内化...
    猜你喜欢
    • 2018-04-15
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多