Immutable link after volatile borrowing

I read about rust last week and (tried) to play with it. I seem to encounter similar issues related to ownership / borrowing every time I use it, so here is the simplest part of the code that illustrates common problems.

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());
    }
}

After reading RefCell I, although it works and actually compiles, but panics at runtime. So my question is: how do I bind a vector to iterate over the same vector? Is there a better data structure allowing me to do this?

-

The documentation Rchas an example in which it is used Weak<T>, which, I think, will work here, but it is not yet stable.

+4
source share
1 answer

, Vec : .

String 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());
}
+4

All Articles