2015-05-13 40 views
1

我試圖寫一個鐵的插件中間件,但我試圖定義一個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

回答

3

這裏是Key定義:

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

即,它延伸性狀Any

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

這意味着,任何類型的,它實現Key還必須實施Any,以及任何Value assoc關聯類型實例化還必須實現Any。但是,Any僅針對'static類型定義,即不包含非靜態引用。

類型的參數是終身的參數,如您Database,通常都含有這種提法(實際上,你的類型包含&'a場),所以它們不是'static,所以他們無法實現Any。因此這些類型不能實現Key。而這其實就是你的錯誤左右,即使這不是很明顯的:

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

無論如何,這個錯誤的核心原因就是鏽目前不支持反射與Any非靜態類型 - 據我所知,在這裏生活中有一些健全的問題。所以目前您唯一的選擇是重構您的程序,因此您不需要在TypeMap中存儲非'static類型。