简体   繁体   English

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

[英]How can I specify a lifetime for closure arguments?

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

I have a closure that takes a slice and returns a subslice of it. 我有一个需要切片并返回其子切片的闭包。 Compiling the following code on rust-1.0.0-beta-2 fails: 在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);
}

I know how to define a lifetime in a closure's type (using for <'a> ), but I don't know how to specify it in the closure's implementation. 我知道如何在闭包的类型中定义生存期( for <'a> ),但是我不知道如何在闭包的实现中指定生存期。

Your implementation impl<F> OptionalFirst for F where F: Fn(&[usize]) -> &[usize] is expecting a bound lifetime parameter, for the constraint F: Fn(&[usize]) -> &[usize] is, expanded to full form: F: for<'a> Fn(&'a [usize]) -> &'a [usize] . impl<F> OptionalFirst for F where F: Fn(&[usize]) -> &[usize]实现impl<F> OptionalFirst for F where F: Fn(&[usize]) -> &[usize]对于约束F: Fn(&[usize]) -> &[usize] impl<F> OptionalFirst for F where F: Fn(&[usize]) -> &[usize]期望绑定的生存期参数。是,展开为完整形式: F: for<'a> Fn(&'a [usize]) -> &'a [usize]

That is, at the time you call the function, it will determine what values to select for the lifetime (they are generics). 也就是说,在调用该函数时,它将确定为生命周期选择哪些值(它们是泛型的)。

A closure, however, cannot have any bound lifetime parameters; 但是,闭包不能具有任何绑定的生存期参数; they are by stuck using concrete lifetime parameters. 他们通过使用具体的寿命参数而陷入困境。 They lack the facility to wire output lifetimes to input lifetimes generically as you want: they are by very design concrete and not generic. 它们缺乏将输出寿命与输入寿命连接起来的功能,就像您想要的那样:它们是非常具体的设计,而不是通用的。 I haven't thought about this in great depth, but it might be possible to counteract this for generic lifetime parameters; 我还没有对此进行深入的思考,但是对于通用的生命周期参数, 可能有可能抵消它。 it is not, however, something that is implemented as far as I am aware. 据我所知,它并没有实现。

If you want something like this, try using a function rather than a closure. 如果您想要这样,请尝试使用函数而不是闭包。 When you're not using any of the environment there's no benefit to using closures beyond the typically lower verbosity. 当您不使用任何环境时,使用闭包通常没有什么好处,这没有任何好处。

Here's what you end up with: 这是您最终得到的结果:

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

Playpen 游戏围栏

You can create a closure with bound lifetime parameters, you just have to get the compiler to infer that type correctly. 您可以使用绑定的生存期参数创建一个闭包,只需要让编译器正确推断该类型即可。 It can be done like this: 可以这样完成:

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);
}

However, what I don't know is how to cast it further into Box<OptionalFirst> . 但是,我不知道如何将其进一步转换为Box<OptionalFirst>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM