将非静态寿命传递给火箭队的管理层

wil*_*ire 3 rust rust-rocket

如何将具有非静态寿命的对象传递给Rocket manage?目前,我遵循以下原则:

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

  Ok(())
}
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:

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...
Run Code Online (Sandbox Code Playgroud)

要添加更多上下文,Bar是一个struct包含框的闭包,它们使用运行时参数进行初始化。args包含密码,密钥和机密之类的东西-实际代码是开源的,因此可以在此处找到。它是WIP,所以会有所变化,并且不是最新的,但希望能为最终目标提供一个思路。

use*_*968 5

您不能使用非静态生存期,因为的manage()字面意义为Send + Sync + 'staticState文档中说明了这样做的原因:

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

也就是说,由于(工作人员)线程可以随时访问托管状态,并且由于无法保证这些线程何时退出,因此托管状态的生存时间至少应与整个程序一样长。那是'static

你可以试着改变你foo()bar: Bar<'static>的,而不是一个普通的一生,并从那里您的方式工作。'static通常,对它的要求并不像听起来那样糟糕,因为所有拥有的值(例如String::new()'static只要不包含对其他事物的引用即可。

如果您不能提供Bar<'static>,则可以使用Arc而不是简单的引用,因此Bar<'a>成为Bar。这里的基本原理是Bar保存原子计数引用,而不是引用,因此要Bar保证所有成员都还活着而Bar还活着。这使Bar 'static


作为一个侧面说明:想着什么时候这可能是有益的'static,对于一些类型是需求'static确实意味着该值呢,其实,长生不老。它只是意味着该值可以作出长生不老。在您的情况下,State无法强制其他线程退出并破坏其值。因此,State必须保证它所操作的所有值可以长期存在State。仅当这些值'static在线程边界处时,才如此。