Reputation: 323
I want passing HashMap and element - Foo to my function. I don't understand variables lifetimes. Please help.
Result : error[E0623]: lifetime mismatch
use std::collections::HashMap;
#[derive(Debug)]
struct Foo<'a> {
x: &'a i32,
}
fn add_to_map<'l>(map: &'l HashMap<u32, &'l Foo>, element : &'l Foo)
{
map.insert(1, element);
}
fn main()
{
let mut map: HashMap<u32, &Foo> = HashMap::new();
let v = 5;
let mut f = Foo { x: &v };
add_to_map(&map, &f);
println!("now f is {:?}", f);
}
Compiler output:
error[E0623]: lifetime mismatch
--> src/main.rs:11:19
|
9 | fn add_to_map<'l>(map: &'l HashMap<u32, &'l Foo>, element : &'l Foo)
| --- --- these two types are declared with different lifetimes...
10 | {
11 | map.insert(1, element);
| ^^^^^^^ ...but data from `element` flows into `map` here
error: aborting due to previous error
Upvotes: 1
Views: 224
Reputation: 58547
9 | fn add_to_map<'l>(map: &'l HashMap<u32, &'l Foo>, element : &'l Foo)
| --- --- these two types are declared with different lifetimes...
10
Foo<'a>
appears twice here ('a
is the lifetime of x
inside Foo
). Since you didn't give explicit values for the lifetime 'a
, the compiler will assume that the Foo
as the HashMap
value and element
Foo
will have different lifetimes 'a
. This approach works well in general.
However, you want to actually insert element
into map
which requires
matching lifetimes. The compiler rejects your code since the lifetimes do not
match. You need to be explicit about the lifetimes of the x
inside Foo
, e.g.,
// Verbose.
fn add_to_map<'l>(map: &'l mut HashMap<u32, &'l Foo<'l>>, element : &'l Foo<'l>)
You do not need to give an explicit lifetime of map
itself since the compiler can verify at the callsite that map
lives at least as long as element
,
// Slightly less verbose.
fn add_to_map<'l>(map: &mut HashMap<u32, &'l Foo<'l>>, element : &'l Foo<'l>)
Note that in any case map
needs to be mut
in add_to_map
.
Upvotes: 4