I have a function square
which I made into a FnMut
by having some state it modifies, namely applied_count
.
This function can be applied with transform(vec![1,3,4], vec![func])
.
where transform
only takes FnOnce
because thats the most less restrictive function trait it needs. However there is a borrow problem which I dont understand.
n main() {
let numbers = vec![1, 2, 5, 9];
let mut applied_count = 0;
let square = |x: &[i32]| -> Vec<i32> {
applied_count += 1;
x.iter().map(|x| x * x).collect()
};
let a: Box<dyn FnOnce(&[i32]) -> Vec<i32>> = Box::new(square);
let res = transform(&numbers, vec![a]);
print!("Result: {res:?}, {applied_count}")
}
fn transform(numbers: &[i32], funcs: Vec<Box<dyn FnOnce(&[i32]) -> Vec<i32>>>) -> Vec<i32> {
let mut res = vec![];
let mut current = numbers;
for f in funcs {
res = f(current);
current = &res;
}
return res;
}
The compiler somehow tells me that the lifetime constraint of FnOnce
becomes + 'static
:
note: due to object lifetime defaults,
`Box<dyn for<'a> FnOnce(&'a [i32]) -> Vec<i32>>` actually means
`Box<(dyn for<'a> FnOnce(&'a [i32]) -> Vec<i32> + 'static)>`
- What does it mean? Does it mean the
&mut i32
captured variable must outlive 'static -> meaning itself must be `'static'. - Why does that happen when the function
transform
is called and not otherwise when I calla(&numbers)
? - How can I pass the the list of closures to the
transform
(its a sink, for all closures the lifetime ends atf(current)
(I guess)) and later accessapplied_count
?
error[E0597]: `applied_count` does not live long enough
--> exercises/closures/src/bin/03-solution.rs:11:9
|
9 | let mut applied_count = 0;
| ----------------- binding `applied_count` declared here
10 | let square = |x: &[i32]| -> Vec<i32> {
| ----------------------- value captured here
11 | applied_count += 1;
| ^^^^^^^^^^^^^ borrowed value does not live long enough
...
15 | let a: Box<dyn FnOnce(&[i32]) -> Vec<i32>> = Box::new(square);
| ---------------- cast requires that `applied_count` is borrowed for `'static`
...
19 | }
| - `applied_count` dropped here while still borrowed
|
= note: due to object lifetime defaults, `Box<dyn for<'a> FnOnce(&'a [i32]) -> Vec<i32>>` actually means `Box<(dyn for<'a> FnOnce(&'a [i32]) -> Vec<i32> + 'static)>`