假设我有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我希望返回的Vec
与foo()
具有相同的生命周期?我的意思是有这个明显的解决方案,但我觉得应该有更好的方法:
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.
}
答案 0 :(得分:12)
正如Shepmaster所提到的,这是一个使用条目模式的例子。起初看起来很冗长,但是这样可以避免分配一个你可能不会使用的数组,除非你需要它。我相信你可以围绕这个做一个通用的功能来减少喋喋不休:)
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");
}
答案 1 :(得分:6)
如果您要将dummy
添加到地图中,则会与How to properly use HashMap::entry?或Want to add to HashMap using pattern match, get borrow mutable more than once at a time(或有关entry
API的任何问题)重复。< / p>
如果您不想添加它,那么您的代码很好,您只需要按照编译器错误消息来修复它。您正在尝试使用关键字作为标识符(ref
),并且需要将可变引用添加到dummy
(& mut dummy
):
use std::collections::HashMap;
fn foo() {
let mut map: HashMap<&str, Vec<&str>> = HashMap::new();
let mut dummy: Vec<&str> = Vec::new();
let f = map.get_mut("whatever").unwrap_or( &mut dummy );
}
fn main() {}