假设我有一个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.
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为它的寿命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.
}
Run Code Online (Sandbox Code Playgroud)
joc*_*ull 13
正如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");
}
Run Code Online (Sandbox Code Playgroud)
这也可以缩短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");
}
Run Code Online (Sandbox Code Playgroud)
如果你想将你添加dummy到地图中,那么这是如何正确使用HashMap :: entry的副本?或者想要使用模式匹配添加到HashMap,一次多次借用可变的(或任何关于entryAPI的问题).
如果您不想添加它,那么您的代码很好,您只需要按照编译器错误消息来修复它.您正在尝试使用关键字作为标识符(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() {}
Run Code Online (Sandbox Code Playgroud)