Rust:“返回这个值要求'op '必须比'static'”存活,并且闭包返回future

beq87vna  于 2023-01-21  发布在  其他
关注(0)|答案(1)|浏览(146)

考虑下面这个最小的例子:

type Task<'a> = Box<dyn std::future::Future<Output = ()> + 'a>;

type Context<'s> = &'s str;

trait MyTrait {
    fn compute<'a>(&'a self, ctx: Context<'a>) -> Task<'a>
    where
        Self: 'a;
}

impl<F: for<'b> Fn(Context<'b>) -> Task<'b>> MyTrait for F {
    fn compute<'a>(&'a self, ctx: Context<'a>) -> Task<'a>
    where
        Self: 'a,
    {
        (self)(ctx)
    }
}

fn bla<'op>(input: &'op usize) -> impl MyTrait + 'op {
    let v: Box<dyn for<'b> Fn(Context<'b>) -> Task<'b> + 'op> = Box::new(move |ctx| {
        Box::new(async move {
            println!("{}", &ctx[*input..]);
            ()
        })
    });
    v
}

编译器生成的错误消息为:

error: lifetime may not live long enough
  --> src/main.rs:22:9
   |
20 |   fn bla<'op>(input: &'op usize) -> impl MyTrait + 'op {
   |          --- lifetime `'op` defined here
21 |       let v: Box<dyn for<'b> Fn(Context<'b>) -> Task<'b> + 'op> = Box::new(move |ctx| {
22 | /         Box::new(async move {
23 | |             println!("{}", &ctx[*input..]);
24 | |             ()
25 | |         })
   | |__________^ returning this value requires that `'op` must outlive `'static`

我不明白为什么'op一定要比'static长,返回的Task的生存期受'b的限制,而'b又比装箱闭包的Self短,因此也比'op短。
我还尝试更明确地对trait对象的生命周期建模,但从下面的代码中得到了相同的错误消息:

type Task<'a> = Box<dyn std::future::Future<Output = ()> + 'a>;

type Context<'s> = &'s str;

trait MyTrait<'l> {
    fn compute<'a>(&'l self, ctx: Context<'a>) -> Task<'l>
    where
        'l: 'a;
}

impl<'c, F: 'c + for<'b> Fn(Context<'b>) -> Task<'b>> MyTrait<'c> for F {
    fn compute<'a>(&'c self, ctx: Context<'a>) -> Task<'c>
    where
        'c: 'a,
    {
        (self)(ctx)
    }
}

fn bla<'op>(input: &'op usize) -> impl MyTrait<'op> + 'op {
    let v: Box<dyn for<'b> Fn(Context<'b>) -> Task<'b> + 'op> = Box::new(move |ctx| {
        Box::new(async move {
            println!("{}", &ctx[*input..]);
            ()
        })
    });
    v
}

编辑:我猜另一种更开放的问这个问题的方式会是:如何用一个外部生命周期来约束一个HRTB的生命周期?

6ss1mwsb

6ss1mwsb1#

我不明白为什么'op一定要比'static长,返回的Task的生存期受'b的限制,而'b又比装箱闭包的Self短,因此也比'op短。
谁说的?编译器唯一知道的是它必须在 * any * lifetime(HRTB)内为真。* any * lifetime包括'static,因此编译器需要'op: 'b,这意味着'op: 'static

相关问题