【问题标题】:Iron persistent state with struct reference具有结构引用的 Iron 持久状态
【发布时间】:2019-05-08 03:54:06
【问题描述】:

我正在努力获得与 Iron 一起使用的持久引用,不知道如何设置适当的生命周期。我希望能够在不同的路线上重复使用控制器。

示例:

use iron::prelude::*;
use iron::typemap::Key;
use persistent::Read;
use router::Router;

pub struct Controller;

pub struct Rest {
    controller: Controller,
}

impl Key for &Controller {
    type Value = Self;
}

impl Rest {
    pub fn run(&self) {
        let router = Router::new();
        let mut chain = Chain::new(router);
        chain.link(Read::<&Controller>::both(&self.controller));
        Iron::new(chain).http(format!("0.0.0.0:1234")).ok();
    }
}

fn main() {
    Rest {
        controller: Controller,
    }
    .run();
}
[dependencies]
iron = "0.6.*"
router = "0.6.*"
persistent = "0.4.0"

Gist of example

error[E0478]: lifetime bound not satisfied
  --> src/main.rs:12:6
   |
12 | impl Key for &Controller {
   |      ^^^
   |
note: lifetime parameter instantiated with the lifetime '_ as defined on the impl at 12:14
  --> src/main.rs:12:14
   |
12 | impl Key for &Controller {
   |              ^
   = note: but lifetime parameter must outlive the static lifetime

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'_` due to conflicting requirements
  --> src/main.rs:12:6
   |
12 | impl Key for &Controller {
   |      ^^^
   |
note: first, the lifetime cannot outlive the lifetime '_ as defined on the impl at 12:14...
  --> src/main.rs:12:14
   |
12 | impl Key for &Controller {
   |              ^
   = note: ...so that the types are compatible:
           expected typemap::Key
              found typemap::Key
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `&Controller` will meet its required lifetime bounds
  --> src/main.rs:12:6
   |
12 | impl Key for &Controller {
   |      ^^^

【问题讨论】:

  • 我希望能够在不同的路由上重复使用控制器——你希望持久数据在所有这些路由之间共享,还是每个路由都共享?路由有自己独特的持久数据?
  • 我希望在所有这些路由中全局共享持久数据。

标签: rust iron


【解决方案1】:

如错误消息所述:

但生命周期参数必须比静态生命周期更长

这是因为Key 使用Any 作为超特征,这需要'static

pub trait Any: 'static {
    fn type_id(&self) -> TypeId;
}

最简单的解决方案是为一个值实现Key,然后将该值赋给Read::both

impl Key for Controller {
    type Value = Self;
}

impl Rest {
    pub fn run(self) {
        let router = Router::new();
        let mut chain = Chain::new(router);
        chain.link(Read::<Controller>::both(self.controller));
        Iron::new(chain).http(format!("0.0.0.0:1234")).ok();
    }
}

我希望在所有这些路由中全局共享持久数据

在这种情况下,我会完全避免使用持久板条箱,而只创建一个单例:

【讨论】:

  • 如果我想引用控制器,更复杂的解决方案会是什么样子?
  • @BriceLechatellier 对含糊不清的措辞感到抱歉 — no 方法可以实现 Key 以供参考,除非参考是 'static(也称为全局),所以没有“复杂”的解决方案。我的意思是提供的解决方案是最简单的工作解决方案,从您提出的结构开始。我已经链接到备用问答,展示如何拥有这样的全球性。
【解决方案2】:

您需要添加绑定到 impl 块的显式生命周期。否则编译器不知道控制器引用的引用有效性。

这应该可以,虽然我还没有测试过

pub struct Rest {
    controller: controller::Controller,
}

impl<'a> Key for &'a controller::Controller {
    type Value = Self;
}

impl Rest {
    pub fn run(&self) {
        let mut router = Router::new();
        let mut chain = Chain::new(router);
        chain.link(Read::<&controller::Controller>::both(&self.controller));
        Iron::new(chain).http(format!("0.0.0.0:1234"))
    }
}

附带说明,我认为您不需要在 Read 调用中指定类型,编译器应该能够从上下文中确定它。

【讨论】:

  • 谢谢,用建议编辑了主要问题,仍然抛出关于生命周期的错误。
猜你喜欢
  • 2019-10-27
  • 2021-01-30
  • 1970-01-01
  • 2013-04-17
  • 2021-02-15
  • 1970-01-01
  • 2019-05-12
  • 1970-01-01
  • 2019-11-24
相关资源
最近更新 更多