HashMap的默认可变值 [英] Default mutable value from HashMap

查看:56
本文介绍了HashMap的默认可变值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个HashMap,并且想要获得对某个条目的可变引用,或者如果该条目不存在,我想要对一个新对象的可变引用,该怎么办?我试过使用unwrap_or(),类似这样:

Suppose I have a HashMap and I want to get a mutable reference to an entry, or if that entry does not exist I want a mutable reference to a new object, how can I do it? I've tried using unwrap_or(), something like this:

fn foo() {
    let mut map: HashMap<&str, Vec<&str>> = HashMap::new();

    let mut ref = map.get_mut("whatever").unwrap_or( &mut Vec::<&str>::new() );

    // Modify ref.
}

但是这不起作用,因为Vec的生存期不够长.有没有办法告诉Rust我希望返回的Vecfoo()具有相同的生存期?我的意思是,有一个明显的解决方案,但我觉得应该有一个更好的方法:

But that doesn't work because the lifetime of the Vec isn't long enough. Is there any way to tell Rust that I want the returned Vec to have the same lifetime as foo()? I mean there is this obvious solution but I feel like there should be a better way:

fn foo() {
    let mut map: HashMap<&str, Vec<&str>> = HashMap::new();

    let mut dummy: Vec<&str> = Vec::new();
    let mut ref = map.get_mut("whatever").unwrap_or( &dummy );

    // Modify ref.
}

推荐答案

如Shepmaster所述,这是使用输入模式的示例.乍一看似乎很冗长,但这避免了分配除非您需要否则就不会使用的数组.我敢肯定,您可以为此创建一个通用函数,以减少震颤:)

As mentioned by Shepmaster, here is an example of using the entry pattern. It seems verbose at first, but this avoids allocating an array you might not use unless you need it. I'm sure you could make a generic function around this to cut down on the chatter :)

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};

fn foo() {
    let mut map = HashMap::<&str, Vec<&str>>::new();
    let mut result = match map.entry("whatever") {
       Vacant(entry) => entry.insert(Vec::new()),
       Occupied(entry) => entry.into_mut(),
    };

    // Do the work
    result.push("One thing");
    result.push("Then another");
}

正如我刚刚发现的,它也可以缩短为or_insert

This can also be shortened to or_insert as I just discovered!

use std::collections::HashMap;

fn foo() {
    let mut map = HashMap::<&str, Vec<&str>>::new();
    let mut result = map.entry("whatever").or_insert(Vec::new());

    // Do the work
    result.push("One thing");
    result.push("Then another");
}

这篇关于HashMap的默认可变值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆