rust - 我如何借用 RefCell<HashMap>、找到一个键并返回对结果的引用?

标签 rust interior-mutability

<分区>

我有一个 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!"));
}

( playground )

如果我删除 RefCell然后一切正常:

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

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

在不复制哈希表中的字符串的情况下编写查找函数的正确方法是什么?

最佳答案

当你从 RefCell 借钱时,您获得的引用的生命周期比 RefCell 短的。那是因为引用的生命周期受到 borrow() 返回的守卫的限制。 .该守卫确保在该守卫被删除之前,没有其他人可以对该值进行可变引用。

但是,您试图在不保持守卫存活的情况下返回一个值。如果Frame有一个方法需要 &self参数但试图改变 map (这可以用 RefCell — 如果你不需要这样做,然后放弃 RefCell 并在改变 map 的方法上写 &mut self),你可能会不小心破坏一个String其他人有引用。这正是借用检查器旨在报告的错误类型!

如果映射值实际上是不可变的(即您的类型不允许改变映射值),您还可以将它们包装在 Rc 中。在你的 map 上。因此,您可以返回 Rc<String> 的克隆(这只会克隆引用计数的指针,而不是底层字符串),这样您就可以在从函数返回之前释放映射上的借用。

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

关于rust - 我如何借用 RefCell<HashMap>、找到一个键并返回对结果的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36648769/

相关文章:

rust - 去除 Url 路径的尾随文件名

rust - Cell 或 RefCell 是最佳选择的情况

rust - 为什么 Mutex 被设计为需要 Rust 中的 Arc

rust - 为什么我的 RefCell 零成本替代方案不是实现内部可变性的标准方法?

rust - 具有内部可变性的细胞,允许任意突变 Action

generics - 如何在 Rust 中使用泛型类型的内部可变性?

rust - 为什么在这个函数中移动了一个迭代器?

rust - 为什么 Rust 程序比 C、Haskell 和 OCaml 版本使用更多的内存?

rust - "use of undeclared type or module"当使用 Diesel 's ` belongs_to` 属性

amazon-web-services - 使用Rusoto上传S3