I have the following code, why the first one is wrong?
Since the data is moved, it can be used in the reduce_move
function, but the compiler given the error: "data does not live long enough "
// error
fn reduce_move<'a, F>(data: Vec<i32>, f: F) where F: FnMut(i32, &'a i32) -> i32 {
let result = data.iter().fold(0i32, f);
println!("{:?}", result);
}
// right
fn reduce_ref<'a, F>(data: &'a Vec<i32>, f: F) where F: FnMut(i32, &'a i32) -> i32 {
let result = data.iter().fold(0i32, f);
println!("{:?}", result);
}
fn main() {
let a: Vec<i32> = vec![1, 2, 3];
let f = |x, y| x + y;
reduce_move(a, f);
//reduce_ref(&a, f);
}
Because 'a
is selected by the caller. No matter what it picks, it must pick a lifetime that lives longer than the call to reduce_move
. data
, by virtue of being moved into reduce_move
, cannot possibly live longer than the call to reduce_move
. Thus, you are trying to create a borrow into data
that lives longer than data
does; this is impossible and the compiler rightly rejects your code.
You can fix this by just not specifying the lifetime yourself and letting the compiler handle it:
fn reduce_move<F>(data: Vec<i32>, f: F) where F: FnMut(i32, &i32) -> i32 {
let result = data.iter().fold(0i32, f);
println!("{:?}", result);
}
fn main() {
let a: Vec<i32> = vec![1, 2, 3];
reduce_move(a, |x, y| x + y);
}
1 Like
Thanks!
I thought the lifetime of 'a
is the same lifetime as the reduce_move
, rather than specified by the caller, so I thought data
live as long as'a
.
And for those who wonder how you would write the lifetimes explicitly here:
fn reduce_move<F>(data: Vec<i32>, f: F) where F: for<'a> FnMut(i32, &'a i32) -> i32
1 Like