How do I borrow a RefCell, find a key, and return a reference to the result? [duplicate]

When you borrow from a RefCell, the reference you get has a shorter lifetime than the RefCell‘s. That’s because the reference’s lifetime is restricted by the guard returned by borrow(). That guard ensures that nobody else can take a mutable reference to the value until the guard is dropped.

However, you are trying to return a value without keeping a guard alive. If Frame had a method that took a &self argument but tried to mutate the map (which is possible with RefCell — if you don’t need to do that, then ditch the RefCell and write &mut self on the methods that mutate the map), you could accidentally destroy a String that somebody else has a reference to. That is exactly the kind of errors that the borrow checker was designed to report!

If the map values are effectively immutable (i.e. your type will not allow mutating the map’s values), you could also wrap them in an Rc in your map. You could therefore return a clone of the Rc<String> (this only clones the reference-counted pointer, not the underlying string), which would let you release the borrow on the map before returning from the function.

struct Frame {
    map: RefCell<HashMap<String, Rc<String>>>
}

impl Frame {
    fn lookup(&self, k: &String) -> Option<Rc<String>> {
        self.map.borrow().get(k).map(|x| x.clone())
    }
}

Leave a Comment