HashMap 从函数获取或插入并返回引用

问题描述 投票:0回答:3

我有以下代码,我想从 HashMap 返回引用(获取或插入新值)并且只进行一次查找。这在 Rust 中可能吗?

这是一个可以玩的游乐场链接。

fn get(key: u32, map: &mut HashMap<u32, String>) -> &mut String {
    match map.entry(key) {
        Entry::Occupied(mut entry) => entry.get_mut(),
        Entry::Vacant(entry) => {
            entry.insert("Hello".into())
        }
    }
}
rust hashmap
3个回答
6
投票

你想要这个吗?

fn get(key: u32, map: &mut HashMap<u32, String>) -> &mut String {
    map.entry(key).or_insert_with(|| "Hello".into())
}

4
投票

使用

Entry::get_mut()
的代码无法编译,因为
get_mut()
返回与条目关联的生命周期。您需要使用
Entry::into_mut()
来代替,它会消耗该条目并返回连接到
HashMap
的引用:

fn get(key: u32, map: &mut HashMap<u32, String>) -> &mut String {
    match map.entry(key) {
        Entry::Occupied(entry) => entry.into_mut(),
        Entry::Vacant(entry) => entry.insert("Hello".into()),
    }
}

游乐场

或者,正如另一个答案所说,您可以使用

or_insert_with()


0
投票

虽然使用

or_insert_with()
( https://stackoverflow.com/a/73801683/8535397 ) 接受的答案在大多数情况下更为惯用,但使用
match map.entry()
into_mut()
( https://stackoverflow.com/a/73805068/8535397)对我有帮助,我想把这个写成答案,因为我认为在特定情况下匹配更有用,我希望这个将来很容易找到。

具体来说,使用匹配允许您在匹配语句中提前返回(或中断),这在插入可能失败并且您希望将错误传递给调用者时很有用,并且还允许您使用问号?运算符(https://doc.rust-lang.org/rust-by-example/std/result/question_mark.html)。反转示例:

use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::num::ParseIntError;

fn get_parsed(
    number_text: String,
    cache: &mut HashMap<String, u32>
) -> Result<&mut u32, ParseIntError> {
    let parsed = match cache.entry(number_text) {
        Entry::Occupied(entry) => entry.into_mut(),
        Entry::Vacant(entry) => {
            // imagine this is an expensive operation that can fail
            let parsed: u32 = entry.key().parse()?;
            entry.insert(parsed)
        }
    };
    Ok(parsed)
}
© www.soinside.com 2019 - 2024. All rights reserved.