2017-10-09 5 views
4

私はデータベースで動作し、保存できるものを表す特性を書き込もうとしています。これを行うために、形質はserde::Deserialize形質を含む他のものを継承する。耐性を必要とする形質を持つRustのジェネリック関数をどのように作成しますか?

trait Storable<'de>: Serialize + Deserialize<'de> { 
    fn global_id() -> &'static [u8]; 
    fn instance_id(&self) -> Vec<u8>; 
} 

struct Example { 
    a: u8, 
    b: u8 
} 

impl<'de> Storable<'de> for Example { 
    fn global_id() -> &'static [u8] { b"p" } 
    fn instance_id(&self) -> Vec<u8> { vec![self.a, self.b] } 
} 

次に、私は一般的な機能を使用してこのデータを記述しようとしています:どのように

error[E0106]: missing lifetime specifier 
--> src/database.rs:180:24 
    | 
180 |  pub fn put<'de, S: Storable>(&mut self, obj: &'de S) -> Result<(), String> { 
    |      ^^^^^^^^ expected lifetime parameter 

Minimal example on the playground.

pub fn put<'de, S: Storable>(&mut self, obj: &'de S) -> Result<(), String> { 
    ... 
    let value = bincode::serialize(obj, bincode::Infinite); 
    ... 
    db.put(key, value).map_err(|e| e.to_string()) 
} 

しかし、私は次のエラーを取得しています私はこれを解決するだろう、それを完全に避けるだろうか?

答えて

3

Storableは、汎用パラメータ(この場合は生涯)で定義されています。つまり、ジェネリックパラメータをアプリケーション全体に伝播する必要があります。

fn put<'de, S: Storable<'de>>(obj: &'de S) -> Result<(), String> { /* ... */ } 

また、ジェネリックを特定することもできます。これは、具体的なタイプまたは生涯(例えば、'static)で行うことも、特性オブジェクトの後ろに置くことによって行うこともできます。

Serdeもa comprehensive page about deserializer lifetimesである。 DeserializeOwnedも同様に使用することができます。

trait Storable: Serialize + DeserializeOwned { /* ... */ } 

あなたにも、あなた自身の形質についてDeserializeOwnedと同じ概念を使用することができます。

trait StorableOwned: for<'de> Storable<'de> { } 

fn put<'de, S: StorableOwned>(obj: &'de S) -> Result<(), String> { 
4

生涯が間違った場所にあります。objの有効期間ではなく、Storableに引数を指定する必要があります。代わりに

fn to_json<'de, S: Storable>(obj: &'de S) -> String { 

使用

fn to_json<'de, S: Storable<'de>>(obj: &S) -> String { 

Playground

ライフタイムがobjの場合は、実際には問題ありません。派生した値が返されていないからです。あなたが証明する必要があるのは、Sは、ある程度の生涯の間Storable<'de>を実装していることです。'de

'deをすべて削除する場合は、the other answerと記載されているDeserializeOwnedを使用してください。

関連する問題