I'm trying to get a handle to an element in a mutable HashMap
reference where the keys are &str
.
In the example below, I'm trying to get value dict[key]
so I can mutate it. How do I do this?
I've tried:
dict.entry(key)
: lifetime mismatchdict.entry(&String::from(key))
: borrowed value does not live long enoughe.g. this:
use std::collections::HashMap;
fn do_thing(key: &str, dict: &mut HashMap<&str, u32>) -> u32 {
let num = dict.entry(&String::from(key)).or_insert(0);
*num += 1;
return 42;
}
Errors out with:
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:4:27
|
3 | fn do_thing(key: &str, dict: &mut HashMap<&str, u32>) -> u32 {
| - let's call the lifetime of this reference `'1`
4 | let num = dict.entry(&String::from(key)).or_insert(0);
| ------------^^^^^^^^^^^^^^^^^- - temporary value is freed at the end of this statement
| | |
| | creates a temporary which is freed while still in use
| argument requires that borrow lasts for `'1`
Link the lifetime of the key
argument to the lifetime of the keys in the HashMap
:
use std::collections::HashMap;
fn do_thing<'a>(key: &'a str, dict: &mut HashMap<&'a str, u32>) -> u32 {
*dict.entry(key).or_insert(0) += 1;
42
}
dict.entry(key)
The error message for this version helps understand the problem:
use std::collections::HashMap;
fn do_thing(key: &str, dict: &mut HashMap<&str, u32>) -> u32 {
*dict.entry(key).or_insert(0) += 1;
42
}
error[E0623]: lifetime mismatch
--> src/lib.rs:4:17
|
3 | fn do_thing(key: &str, dict: &mut HashMap<&str, u32>) -> u32 {
| ---- ----
| |
| these two types are declared with different lifetimes...
4 | *dict.entry(key).or_insert(0) += 1;
| ^^^ ...but data from `key` flows into `dict` here
Specifically, entry
will store key
in the HashMap
, but the value referenced by key
might become invalid before the HashMap
does. If that happened, the HashMap
would contain a dangling reference, pointing to invalid memory. That's exactly what Rust's borrow checker prevents.
See also:
dict.entry(&String::from(key))
This can never work here, for much the same reason.
See also: