我正在努力寻找一种优雅的TO解决方案,以便在Ruust中访问用于只读目的的嵌套 map .我遇到了这种情况,理想情况下,我可以返回对空映射的引用(这当然不起作用,因为空哈希映射归函数所有):

struct S {
    stuff: HashMap<A, HashMap<B, C>>
}

impl S {
    fn get(&self, a: &A) -> &HashMap<B,C> {
        return self.stuff.get(a).unwrap_or(&HashMap::new());
    }
}

不能保证 map 的东西会有关键字a,因此处理可选性是必须的.

我希望解决方案来实现方法得到这个或类似的签名以一种有效的方式(没有副本/移动),因为 map 的东西可能是相当大的.

我只能想到以下解决方案,但我在想,肯定有更直接的解决方案:

  1. 在 struct S中添加一个私有字段,它只是一个空的HashMap,这样我就可以返回的引用.这似乎是一个糟糕的懒惰解决方案.
  2. 调用Entry(A).INSERT_WITH(||HashMap::New()),但这需要不必要的可变性.
  3. 退货选项&lt;&amp;HashMap&gt;

在我看来,解决方案(3)是实现上述目标的最好方法,但也许我错过了一些东西,有更直接的方法吗?

推荐答案

返回Option<&HashMap>既惯用又简单.

fn get(&self, a: &A) -> Option<&HashMap<B,C>> {
    self.stuff.get(a)
}

你可以用&HashMap做的任何事情都可以用Option<&HashMap>做.例如,您可以判断是否存在密钥.

if s.get(&a).map_or(false, |hm| hm.contains_key(&b)) {
    println!("key exists");
}

get返回None时,这将产生false,这与您对空的HashMap调用contains_key的情况相同.

作为额外奖励,包含引用的Option始终是same size in memory as just the reference.

Rust相关问答推荐

在Tauri中获取ICoreWebView 2_7以打印PDF

如何处理动态 struct 实例化?

为什么BitVec缺少Serialize trait?

亚性状上位性状上的 rust 病伴生型界限

有没有办法指定只在Rust的测试中有效的断言?

原始数组数据类型的默认trait实现

自定义结果枚举如何支持`?`/`FromResidual`?

如何将实现多个特征的 struct 传递给接受这些特征为&;mut?

在使用粗粒度锁访问的数据 struct 中使用 RefCell 是否安全?

借来的价值生命周期 不够长,不确定为什么它仍然是借来的

Rust 中多个 & 符号的内存表示

相当于 Rust 中 C++ 的 std::istringstream

通过mem::transmute将数组展平安全吗?

无法将`&Vec>`转换为`&[&str]`

为什么带有生命周期指定的方法不能被调用两次?

Rust 编译器不统一在 if let 表达式的分支中都 impl Future 的类型

如何创建递归borrow 其父/创建者的 struct ?

Rust 异步和 AsRef 未被发送

预期的整数,找到 `&{integer}`

我如何将特征作为 struct 的拥有字段?