Default value changed from HashMap

Suppose I have a HashMap and want to get a mutable link to an entry, or if that entry does not exist, I want to change the link to a new object, how can I do this? I 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. } 

But this does not work, because Vec lifetime is not long enough. Is there any way to tell Rust that I want the returned Vec have the same lifetime as foo() ? I mean there is this obvious solution, but I feel that 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. } 
+7
rust lifetime
source share
2 answers

As mentioned in Shepmaster, here is an example of using an input pattern. At first it looks verbose, but it avoids allocating an array that you cannot use if you do not need it. I'm sure you could make a general function around this to cut 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"); } 

It can also be shortened to or_insert , as I just opened!

 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"); } 
+10
source share

If you want to add your dummy to the map, then this is a duplicate. How to use HashMap :: entry? or Want to add to the HashMap using pattern matching, get a borrow more than once at a time (or any entry API question).

If you do not want to add it, then your code is fine, you just need to follow the compiler error messages to fix this. You are trying to use the keyword as an identifier ( ref ), and you need to get a mutable link to 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() {} 
+6
source share

All Articles