返回从RefCell <T>借来的T

我有一个RefCell<HashMap>并想借用该表,find一个键,并返回结果的引用:

 struct Frame { map: RefCell<HashMap<String, String>> } impl Frame { fn lookup<'a>(&'a self, k: &String) -> Option<&'a String> { // Borrow checker barfs here! self.map.borrow().get(k) //^~~~~~~~~~~~~~~ borrowed value does not live long enough } } 

( 围栏 )

如果我删除RefCell东西,那么一切工作正常:

 struct Frame { map: HashMap<String, String> } impl Frame { fn lookup<'a>(&'a self, k: &String) -> Option<&'a String> { self.map.get(k) } } 

什么是正确的方式来编写查找函数而不复制散列表中的string?

当您从RefCell借用时,您获得的参考资料的寿命比RefCell的寿命短。 这是因为引用的生命期限是由borrow()返回的守卫限制的。 那个后卫确保没有其他人可以对这个值进行可变的引用,直到守卫被丢弃。

但是,你正在试图在没有保持警惕的情况下返回一个值。 如果Frame有一个方法需要一个&selfvariables,但试图改变地图(这可能与RefCell – 如果你不需要这样做,然后沟渠RefCell和写&mut self的方法,改变地图),你可能会意外地销毁其他人可以参考的String 。 这正是借用检查器devise报告的那种错误!

如果地图值是不可变的(即,你的types不允许改变地图的值),你也可以把它们包装在地图上的一个Rc中。 因此,您可以返回一个Rc<String>克隆(它只克隆引用计数的指针,而不是底层的string),这会让您在从函数返回之前释放地图上的借位。

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