user1685095
user1685095

Reputation: 6121

How to define lifetimes properly in closure

impl Rate for Vec<VolumeRanged> {
    fn costs<'a, I>(&'a self, issues: &I, period: u32) -> Box<'a + Iterator<Item = f32>>
    where
        I: IntoIterator<Item=f32>,
        I::IntoIter: 'a
    {
        fn issue_cost(issue: f32, percentage: f32, constant: f32, max: f32) -> f32 {
            let r = issue * percentage / 100.0 + constant;
            match r.partial_cmp(&max) {
                Some(Less) => r,
                _ => max
            }
        }
        Box::new(issues.into_iter().map(|i| {
            let (pr, nr) = pairwise(self)
                        .find(|&(_, n)| in_range(&i, &n.range))
                        .expect("No range found");
            issue_cost(
                i,
                nr.percentage,
                pr.map_or(0.0, |x| x.max),
                nr.max,
            )
        }))
    }
}

Rust is saying

error[E0373]: closure may outlive the current function, but it borrows `self`, which is owned by the current function
  --> src/main.rs:43:41
   |
43 |         Box::new(issues.into_iter().map(|i| {
   |                                         ^^^ may outlive borrowed value `self`
44 |             let (pr, nr) = pairwise(self)
   |                                     ---- `self` is borrowed here
   |
help: to force the closure to take ownership of `self` (and any other referenced variables), use the `move` keyword
   |
43 |         Box::new(issues.into_iter().map(move |i| {
   |                                         ^

But I don't want to move ownership into closure. What I want is that returned boxed iterator should live as long as both self and issues. As soon as they go away - it should go away.

I know that this can be solved by passing cloned iterator to issues instead of a reference to it, I don't think that It's needed here.

playground

Upvotes: 2

Views: 166

Answers (1)

red75prime
red75prime

Reputation: 3861

Add move to the closure. self has type &Vec<VolumeRanged>, so closure will not take ownership of the vector, it will capture the reference to the vector.

Upvotes: 1

Related Questions