【问题标题】:Trait type and lifetime issues特征类型和生命周期问题
【发布时间】:2015-05-13 15:41:52
【问题描述】:

我正在尝试编写 Iron 插件中间件,但在尝试定义 typemap 键时遇到了问题:

简单类型的最小示例可以正常工作:

pub struct Database;
impl Key for Database {
    type Value = isize;
}

但是一旦涉及生命周期,我就无法编译库:

pub struct Database<'a> {
    pool: &'a Arc<Pool<PostgresConnectionManager>>
}

impl<'a> Key for Database<'a> {
    type Value = PooledConnection<'a, PostgresConnectionManager>;
}

这里发生了什么?我得到错误:

src/lib.rs:33:1: 35:2 note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 33:0...
src/lib.rs:33 impl<'a> Key for Database<'a> {
src/lib.rs:34     type Value = PooledConnection<'a, PostgresConnectionManager>;
src/lib.rs:35 }
src/lib.rs:33:1: 35:2 note: ...so that trait type parameters matches those specified on the impl (expected `typemap::Key`, found `typemap::Key`)
src/lib.rs:33 impl<'a> Key for Database<'a> {
src/lib.rs:34     type Value = PooledConnection<'a, PostgresConnectionManager>;
src/lib.rs:35 }
note: but, the lifetime must be valid for the static lifetime...
src/lib.rs:33:1: 35:2 note: ...so that the type `r2d2::PooledConnection<'_, r2d2_postgres::PostgresConnectionManager>` will meet its required lifetime bounds
src/lib.rs:33 impl<'a> Key for Database<'a> {
src/lib.rs:34     type Value = PooledConnection<'a, PostgresConnectionManager>;
src/lib.rs:35 }

但这对我来说没有意义 - PooledConnection 不能比经理长寿,而 Arc&lt;Pool&lt;...Manager&gt;&gt; 被赋予了生命周期来确保这一点。我在这里错过了什么?

(documentation for Pool)

【问题讨论】:

    标签: rust lifetime


    【解决方案1】:

    这里是Key的定义:

    pub trait Key: Any {
        type Value: Any;
    }
    

    也就是说,它扩展了 trait Any:

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

    这意味着任何实现Key 的类型也必须实现Any,并且任何Value 关联的类型实例化也必须实现Any。但是,Any 仅针对 'static 类型定义,即不包含非静态引用。

    使用生命周期参数参数化的类型,例如您的Database,通常确实包含此类引用(实际上,您的类型包含&amp;'a 字段),因此它们不是'static,因此它们无法实现Any .因此此类类型无法实现Key。这实际上就是您的错误所在,即使这不是很明显:

    note: but, the lifetime must be valid for the static lifetime...
    

    无论如何,这个错误的核心原因是 Rust 目前不支持使用 Any 进行非静态类型的反射——据我所知,这里存在一些关于生命周期的健全性问题。所以目前你唯一的选择是重构你的程序,这样你就不需要在TypeMap 中存储非'static 类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-18
      • 1970-01-01
      • 2015-04-22
      • 1970-01-01
      • 1970-01-01
      • 2018-03-19
      相关资源
      最近更新 更多