将非静态生命周期传递给Rocket的管理

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

如何将具有非静态生命周期的对象传递给Rocket的manage?目前我有以下几点:

fn foo<'a>(bar: Bar<'a>) -> Result<(), Error> {
  rocket::ignite()
    .manage(bar)
    .mount("/", routes![index])
    .launch();

  Ok(())
}

但是我收到以下错误:

cannot infer an appropriate lifetime due to conflicting requirements

note: ...so that the expression is assignable:
      expected bar::Bar<'_>
         found bar::Bar<'a>
note: but, the lifetime must be valid for the static lifetime...

要添加更多上下文,Bar是一个包含盒装闭包的struct,它使用运行时args初始化。 args包含密码,密钥和秘密之类的东西 - 实际的代码是开源的,所以可以找到here。这是WIP,所以会改变,并不是完全最新的,但希望能为最终目标提供一个想法。

rust rust-rocket
1个回答
1
投票

你不能使用非静态生命,因为manage()的签名字面上说Send + Sync + 'static。其原因在documentation for State中说明:

被管理的类型必须是线程安全的,并且可以跨线程边界发送。换句话说,它必须实现Send + Sync +'静态。

也就是说,由于(工作者)线程可以随时访问托管状态,并且由于无法保证这些线程何时可以退出,因此托管状态必须至少与整个程序一样长;这是'static

你可以尝试改变你的foo()来取代bar: Bar<'static>而不是通用的生命周期并从那里开始工作。 'static的要求通常没有听起来那么糟糕,因为所有拥有的值(如String::new())都是'static,只要它们不包含对其他内容的引用。

如果你不能提供Bar<'static>,你可以使用Arc而不是普通参考,所以Bar<'a>变成Bar。这里的基本原理是Bar持有原子计数的参考而不是参考,所以持有Bar保证所有成员都活着,而Bar还活着。这使得Bar 'static

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