【问题标题】:How to define lifetimes properly in closure如何在闭包中正确定义生命周期
【发布时间】:2017-10-05 09:21:41
【问题描述】:
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,
            )
        }))
    }
}

锈在说

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| {
   |                                         ^

但我不想关闭所有权。我想要的是返回的盒装迭代器应该与selfissues 一样长。他们一走,它就应该走。

我知道这可以通过将克隆的迭代器传递给 issues 而不是对它的引用来解决,我认为这里不需要它。

playground

【问题讨论】:

    标签: rust lifetime


    【解决方案1】:

    move 添加到闭包中。 self 具有 &amp;Vec&lt;VolumeRanged&gt; 类型,因此闭包不会获得向量的所有权,它会捕获对向量的引用。

    【讨论】:

    • 闭包的寿命应该和issuesself 一样长,而不是相反。
    • 生命周期注释不会改变实际生命周期。添加move 将阻止您引用已释放的向量,仅此而已。不添加move 将不允许程序编译,因为闭包会捕获对函数参数self 的引用,该参数仅存在于函数内部。
    • 如果问题出在self,为什么要移动来自issuesi
    • 除此之外你试过吗?这将导致另一个错误。
    • i 是一个闭包参数,它不受move 的影响。另一个错误(无法移出借来的内容)与您的问题没有直接关系。 into_iter() 尝试消费 *issues,但无法移出借用内容。将&amp;I 替换为I 以摆脱它。
    猜你喜欢
    • 1970-01-01
    • 2021-12-04
    • 2020-12-10
    • 1970-01-01
    • 1970-01-01
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    • 2015-10-02
    相关资源
    最近更新 更多