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

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()的生命周期 相同?我的意思是有一个显而易见的解决方案,但我觉得应该有更好的方法:

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所提到的,下面是一个使用输入模式的示例.一开始看起来很冗长,但这避免了分配一个除非需要否则可能不会使用的array.我相信你可以做一个通用函数来减少聊天:)

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

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");
}

Rust相关问答推荐

移植带有可变borrow 的C代码-卸载期间错误(nappgui示例)

为什么在Rust struct 中只允许最后一个字段具有动态大小的类型

创建包含缺失值的框架

通过使用光标拖动角来绕其中心旋转矩形

编译项目期间使用Cargo生成时出现rustc错误

如何为rust trait边界指定多种可能性

使用铁 rust S还原对多个数组执行顺序kronecker积

如果死 struct 实现了/派生了一些特征,为什么Rust会停止检测它们?

AXUM一路由多个不包括URL的参数类型

为什么 Rust 需要可变引用的显式生命周期而不是常规引用?

为什么编译器看不到这个 `From` impl?

Button.set_hexpand(false) 不会阻止按钮展开

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

Rust并发读写引起的死锁问题

在不安全的 Rust 中存储对 struct 内部数据的静态引用是否合法?

简单 TCP 服务器的连接由对等重置错误,mio 负载较小

为什么可以在迭代器引用上调用 into_iter?

从 Cranelift 发出 ASM

为什么 `ref` 会导致此示例*取消引用*一个字段?

在 macro_rules 中转义 $ 美元符号