You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust访问值为Option的HashMap时如何避免对返回值调用unwrap?

优化方案

你代码里的unwrap完全是不必要的,根源是你给HashMap的value套了一层多余的Option:你的所有插入操作都只会存入Some(计算结果),永远不会出现None的情况,直接把hmap的类型改为HashMap<u32, u32>就能直接删掉这个unwrap。

在此基础上,Rust针对HashMap「存在即返回、不存在则计算插入」的场景,提供了更符合惯用写法的entry API,无需手动写match分支,代码更简洁鲁棒。

优化后完整代码

use std::collections::HashMap;

struct Cacher<T> {
    calculation: T,
    hmap: HashMap<u32, u32>,
}

impl<T> Cacher<T>
where
    T: Fn(u32) -> u32,
{
    fn new(calculation: T) -> Cacher<T> {
        Cacher {
            calculation,
            hmap: HashMap::new(),
        }
    }

    fn value(&mut self, arg: u32) -> u32 {
        // entry API直接处理命中/缺失逻辑,无需unwrap
        *self.hmap.entry(arg).or_insert_with(|| (self.calculation)(arg))
    }
}

fn main() {
    let mut cache = Cacher::new(|x| x * x);
    let v = vec![cache.value(1), cache.value(2), cache.value(3)];
    println!("v: {:?}", v);
}

代码说明

  • entry方法会返回键对应的条目枚举,要么是已存在的Occupied,要么是不存在的Vacant
  • or_insert_with方法会在条目为空时,调用传入的闭包计算值插入,最后返回条目的可变引用
  • 这里的解引用*是为了拿到u32类型的返回值,符合原方法的返回签名

如果确实有场景需要在HashMap里存Option<u32>(比如要缓存的计算逻辑本身可能返回None),那也可以用嵌套模式匹配代替unwrap,写法如下:

// 仅针对必须存Option的场景的兼容写法
match self.hmap.get(&arg) {
    Some(Some(v)) => *v,
    _ => {
        let v = (self.calculation)(arg);
        self.hmap.insert(arg, Some(v));
        v
    }
}

这种写法完全避免了unwrap,就算后续你逻辑改成会存None也不会触发panic,鲁棒性更高。

内容的提问来源于stack exchange,提问作者magnusmaehlum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 23:06:04