我有一个RefCell<HashMap>
,想要借用这个表格,查找一个键,并返回结果的引用:
use std::cell::RefCell;
use std::collections::HashMap;
struct Frame {
map: RefCell<HashMap<String, String>>,
}
impl Frame {
fn new() -> Frame {
Frame {
map: RefCell::new(HashMap::new()),
}
}
fn lookup<'a>(&'a self, k: &String) -> Option<&'a String> {
self.map.borrow().get(k)
}
}
fn main() {
let f = Frame::new();
println!("{}", f.lookup(&"hello".to_string()).expect("blargh!"));
}
如果我删除 RefCell
,那么一切都正常:
struct Frame {
map: HashMap<String, String>,
}
impl Frame {
fn lookup<'a>(&'a self, k: &String) -> Option<&'a String> {
self.map.get(k)
}
}
如何在不复制哈希表中的字符串的情况下编写正确的查找函数?
borrow_mut()
,那么使用RefCell
就毫无意义了。直接将HashMap
存储在你的Frame
中即可。如果你想避免复制/克隆,那么返回一个引用,这就是它们的目的! - Francis GagnéRefCell
本质上是一种读写锁,虽然不是线程安全的;当你调用.borrow_mut()
方法时,它会检查没有其他人已经持有借用(写入需要独占访问权限),而当你调用.borrow()
方法时,它会检查没有写入操作进行中(读者获得共享访问权限)。为了确保RefCell
具有写入专属性,这意味着通过.borrow()
方法借用的内容不能比守卫(Ref<'a, T>
)活得长,这就是你在这里遇到的问题(因为守卫的生命周期不长于函数)。返回一个Rc<String>
已经被证明可以解决这个问题。 - Matthieu M.