如何为闭包参数指定生命周期?

时间:2015-04-18 08:43:34

标签: closures rust lifetime

游戏围栏链接:http://is.gd/EpX6lM

我有一个闭包,它接受一个切片并返回它的一个子切片。在rust-1.0.0-beta-2上编译以下代码失败:

trait OptionalFirst {
    fn optional_first<'a>(&self, x: &'a [usize]) -> &'a [usize];
}

impl<F> OptionalFirst for F where F: Fn(&[usize]) -> &[usize] {
    fn optional_first<'a>(&self, x: &'a [usize]) -> &'a [usize] {
        (*self)(x)
    }
}

fn main() {
    let bc: Box<OptionalFirst> = Box::new(
        |x: &[usize]| -> &[usize] {
            if x.len() != 0 {
                &x[..1]
            }
            else {
                &x[..0]
            }
        }) as Box<OptionalFirst>;

    let a: [usize; 3] = [1, 2, 3];
    let b: &[usize] = bc.optional_first(&a);
    println!("{:?}", b);
}

我知道如何在闭包类型中定义生命周期(使用for <'a>),但我不知道如何在闭包的实现中指定它。

2 个答案:

答案 0 :(得分:3)

您的实施impl<F> OptionalFirst for F where F: Fn(&[usize]) -> &[usize]期望绑定生命周期参数,因为约束F: Fn(&[usize]) -> &[usize]已扩展为完整格式:F: for<'a> Fn(&'a [usize]) -> &'a [usize]

也就是说,在你调用函数时,它将确定在生命周期中选择哪些值(它们是泛型)。

但是,闭包不能有任何绑定的生命周期参数;他们使用具体的生命周期参数。他们缺乏将输出寿命连接到输入寿命的设施,因为它们通常是设计具体而非通用的。我没有深入考虑过这个问题,但可能可以抵消这个通用生命周期参数;但是,据我所知,它并没有实现。

如果你想要这样的东西,尝试使用函数而不是闭包。当你没有使用任何环境时,使用闭包除了通常较低的冗长之外没有任何好处。

以下是您的最终结果:

fn bc(x: &[usize]) -> &[usize] {
    if x.len() != 0 {
        &x[..1]
    } else {
        &x[..0]
    }
}

Playpen

答案 1 :(得分:0)

您可以使用绑定生存期参数创建闭包,只需让编译器正确推断该类型即可。可以这样做:

fn main() {
    let bc: Box<Fn(&[usize]) -> &[usize]> = Box::new(
        |x| {
            if x.len() != 0 {
                &x[..1]
            }
            else {
                &x[..0]
            }
        });

    let a: [usize; 3] = [1, 2, 3];
    let b: &[usize] = bc(&a);
    println!("{:?}", b);
}

然而,我不知道的是如何将其进一步投入Box<OptionalFirst>