当闭包含复杂的生命周期关系时,无法为函数构建等效闭包[重复]

问题描述 投票:1回答:1

这个问题在这里已有答案:

我在使用等效闭包替换函数时遇到了一些麻烦,编译器抱怨

cannot infer an appropriate lifetime due to conflicting requirements

note: ...so that the types are compatible:
      expected &std::collections::BTreeSet<&str>
         found &std::collections::BTreeSet<&str> rustc(E0495)

在封闭中,在ranger.extend(s.range(lower..=upper));method。但我无法弄清楚如何将生命周期提示放在一个闭包中,也许,这是不可能的。

use std::collections::BTreeSet;

fn main() {
    let mut set = BTreeSet::new();

    set.insert("TEST1");
    set.insert("TEST3");
    set.insert("TEST4");
    set.insert("TEST2");
    set.insert("TEST5");

    println!("init: {:?}", set);

    let closure = |lower, upper| {        
        |s: &BTreeSet<&str>| {
            let mut r = BTreeSet::new();
            r.extend(s.range(lower..=upper));
            r
        }
    };

    set = extract_fn("TEST2", "TEST5")(&set);
    set = closure("TEST3", "TEST4")(&set);
    println!("result: {:?}", set);
}

fn extract_fn<'a>(
    lower: &'a str,
    upper: &'a str,
) -> impl Fn(&BTreeSet<&'a str>) -> BTreeSet<&'a str> {
    move |s| {
        let mut r = BTreeSet::new();
        r.extend(s.range(lower..=upper));
        r
    }
}

除了把static生命周期,这种类型的错误的闭包应该转换为函数吗?

rust
1个回答
1
投票

这不能轻易完成,但您可以使用返回类型定义外部闭包,这有助于您为内部闭包设置显式的生命周期边界。 (通过使用for<>这是一个更高级别的特质绑定,你可以找到更多的details in here)。

内部封闭需要进行Boxed,因为在编译时不知道Fn特征的大小。

let closure = |lower, upper| -> Box<for<'a> Fn(&BTreeSet<&'a str>) -> BTreeSet<&'a str>> {
        Box::new(move |s: &BTreeSet<&str>| {
            let mut r = BTreeSet::new();
            r.extend(s.range(lower..=upper));
            r
        })
    };

Playground

© www.soinside.com 2019 - 2024. All rights reserved.