The problem is that the lifetime of v
is for the whole if/else
block, even though it is not available in the else
section. You can get around this by with the help of Option::cloned
.
pub fn calc_deps(cache: &mut HashMap<String, String>, key: &String) -> String {
if let Some(v) = cache.get(key).cloned() {
v
} else {
let r = String::from("computations");
cache.insert(key.clone(), r.clone());
r
}
}
Option::cloned
maps Option<&T>
to Option<T>
by cloning the contents. So now v
becomes String
instead of &String
, and is no longer borrowing cache
.
Another option is to use the HashMap::entry/or_insert_with
interface. It's probably more idiomatic, but it requires unconditionally cloning the key
.
pub fn calc_deps(cache: &mut HashMap<String, String>, key: String) -> String {
cache
.entry(key)
.or_insert_with(|| String::from("computations"))
.clone()
}
You could also simply use or_insert
instead of or_insert_with
, but that would require doing your computations for r
unconditionally.
pub fn calc_deps(cache: &mut HashMap<String, String>, key: String) -> String {
cache
.entry(key)
.or_insert(String::from("computations"))
.clone()
}