【问题标题】:Passing a non-static lifetime to Rocket's manage将非静态生命周期传递给 Rocket 的管理
【发布时间】:2019-09-19 07:39:01
【问题描述】:

如何将具有非静态生命周期的对象传递给 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 包含密码、密钥和机密等内容 - 实际代码是开源的,因此可以在 here 找到。它是 WIP,因此会发生变化,并且不是完全最新的,但希望为最终目标提供一个想法。

【问题讨论】:

  • 您不能使用非静态生命周期,因为manage() 的签名字面意思是Send + Sync + 'static。您可以尝试更改您的 foo() 以采用 bar: Bar&lt;'static&gt; 而不是通用生命周期,然后从那里开始工作。盒装闭包应该是'static,只要它们不捕获非静态生命周期。
  • 感谢您的回复。如果这是答案,可以将其发布为答案吗?不幸的是,这似乎是有限的,你知道为什么它被明确声明为static吗?

标签: rust rust-rocket


【解决方案1】:

您不能使用非静态生命周期,因为manage() 的签名字面意思是Send + Sync + 'static。原因在documentation for State中说明:

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

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

您可以尝试将您的 foo() 更改为采用 bar: Bar&lt;'static&gt; 而不是通用生命周期,然后从那里开始工作。 'static 的要求通常并不像听起来那么糟糕,因为所有拥有的值(如 String::new())都是 'static,只要它们不包含对其他事物的引用。

如果您无法提供Bar&lt;'static&gt;,您也许可以使用Arc 而不是普通引用,因此Bar&lt;'a&gt; 变为Bar。这里的基本原理是 Bar 持有原子计数的引用而不是引用,因此持有 Bar 保证所有成员都处于活动状态,而 Bar 处于活动状态。这使得Bar'static


作为旁注:在考虑 'static 时可能会有所帮助,要求某些类型为 'static 确实意味着该值确实,事实上,永远存在.这只是意味着价值可以永远存在。在您的情况下,State 无法强制其他线程退出并销毁它们的值。因此State 必须保证它所操作的所有值都可以随着State 的需要而存在。仅当这些值在线程边界处为 'static 时才适用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    • 2012-11-24
    相关资源
    最近更新 更多