Reputation: 652
I am having trouble getting a piece of code to work, as the errors I am getting are circular.
I start with the following code:
use std::collections::HashMap;
let mut hashm = HashMap::<Vec<&str>, &str>::new();
for i in v {
let s = i.split('\t').collect::<Vec<&str>>();
let j = s[0]
.replace(&['{', '}'][..], "") // replace multiple at once; https://users.rust-lang.org/t/24554/2
.split(", ")
.collect::<Vec<&str>>();
let k = s[1];
hashm.insert(j, k);
}
The error I get says that s[0]
creates a temporary which is freed while still in use...
hashm.insert(j, k);
- borrow later used here
So I change hashm.insert(j, k)
to hashm.insert(&j, k)
and HashMap::<Vec<&str>, &str>::new();
to HashMap::<&Vec<&str>, &str>::new();
, but then I get the same error, as well as this:
hashm.insert(&j, k);
^^ borrowed value does not live long enough
How can I rectify this?
Upvotes: 2
Views: 140
Reputation: 43902
let mut hashm = HashMap::<Vec<&str>, &str>::new();
The key and value types you have specified here are borrowed. This means that something else must own the keys and values. That can work in some cases, but in this case you're calling str::replace
which returns a newly allocated String
which is then borrowed by split
. That string cannot outlive the loop iteration — in fact, it's freed at the end of the let j
statement. If you assigned the String
to its own temporary variable, it'd last long enough that the call to split
would compile, but it would still be freed at the end of the loop, so inserting it in hashm
would fail.
If you make String
s from the &str
s for the keys then the code will compile:
use std::collections::HashMap;
let mut hashm = HashMap::<Vec<String>, &str>::new();
for i in v {
let s = i.split('\t').collect::<Vec<&str>>();
let j = s[0]
.replace(&['{', '}'][..], "")
.split(", ")
.map(str::to_owned)
.collect();
let k = s[1];
hashm.insert(j, k);
}
Note that this HashMap still cannot live any longer than v
because its values are still borrowed. If that is not what you want, then you must change its type to HashMap<Vec<String>, String>
and use hashm.insert(j, k.to_owned());
.
Upvotes: 2