rust - 特征类型和生命周期问题

标签 rust lifetime

我正在尝试编写 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<Pool<...Manager>>长寿被赋予生命周期以确保这一点。我在这里缺少什么?

( documentation for Pool )

最佳答案

这里是 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,通常包含此类引用(实际上,您的类型包含 &'a 字段),因此它们是不是 'static,因此它们无法实现 Any。因此,此类类型无法实现 Key。这实际上就是您的错误所在,即使这不是很明显:

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

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

关于rust - 特征类型和生命周期问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30219549/

相关文章:

rust - 特征边界 `std::io::Write + ' static: std::marker::Sized` 不满足,当传递闭包时

php - 通过 id 检查 session 是否存在,而不更新 session 的生命周期

rust - 如何在不必处理生命周期的情况下存储引用?

hashmap - 为什么 csv::Reader 记录中的字符串在插入到 HashMap 中时生命周期不够长?

rust - 如何实现可能的突变的通用穿插

rust - 如何使用 toml-rs 检查 TOML 中是否存在 key ?

collections - 如果元素可以转换,为什么不能使用 .into() 转换容器?

types - 使用 Iterator::sum 时,在此上下文中必须知道类型

rust - 无法分配给结构字段,因为它已被借用,但借用的字段在单独的范围内

reference - 借用的值在循环中的生命周期不够长