返回从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
有一个方法需要一个&self
variables,但试图改变地图(这可能与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()) } }