簡體   English   中英

為實現具有關聯生命周期的特征的泛型類型實現特征時的生命周期問題

[英]Lifetime issue while implementing a trait for a generic type which implements a trait with an associated lifetime

我正在為一個項目編寫一個反序列化器( Vec<u8> (Raw JSON) 到任何類型的 T)並嘗試使用 serde 。 這是我解碼數據的特征:

pub trait Decode: Sized {
    fn try_decode(input: Vec<u8>) -> Result<Self, InternalError>;
}

因為我打算在我的結構上使用#[derive(Deserialize)] ,所以我正在為任何實現具有任意生命周期的 Deserialize 特征的類型編寫一個 impl:

impl<'a, T: Deserialize<'a>> Decode for T {
    fn try_decode(input: Vec<u8>) -> Result<Self, InternalError> {
        if let Ok(t) = serde_json::from_slice(&input) {
            Ok(t)
        } else {
            Err(Internal::decode("Could not decode"))
        }
    }
}

但是我遇到了終身錯誤:

error[E0597]: `input` does not live long enough
  --> src/decode.rs:16:47
   |
14 | impl<'a, T: Deserialize<'a>> Decode for T {
   |      -- lifetime `'a` defined here
15 |     fn try_decode(input: Vec<u8>) -> Result<Self, InternalError> {
16 |         if let Ok(t) = serde_json::from_slice(&input) {
   |                        -----------------------^^^^^^-
   |                        |                      |
   |                        |                      borrowed value does not live long enough
   |                        argument requires that `input` is borrowed for `'a`
...
21 |     }
   |     - `input` dropped here while still borrowed

我理解為什么編譯器生我的氣。 在檢查 from_slice 的實現后,我發現它有一個關聯的生命周期。 我確定 input 是一個擁有的值,但 from_slice 需要一個引用,所以在這里我返回一個值的引用,該值在 function 結束時被丟棄,這顯然是不正確的。 我的問題是,有沒有辦法確保在 <'a> 生命周期內借用該值(即此函數的調用者提供的生命周期)。 我無法更新特征,因為它會導致災難。

如果你想要一個不從切片中借用的值,你可以使用DeserializeOwned作為特征綁定,它沒有關聯的生命周期(因此只存儲擁有的值)。 例如,這編譯:

impl<T: DeserializeOwned> Decode for T {
    fn try_decode(input: Vec<u8>) -> Result<Self, InternalError> {
        if let Ok(t) = serde_json::from_slice(&input) {
            Ok(t)
        } else {
            todo!()
        }
    }
}

操場

這等效於使用具有較低級別Deserialize特征界限的較高等級的特征界限:

impl<T: for<'de> Deserialize<'de>> Decode for T {
    // ...
}

使用帶生命周期的反序列化的正確方法是使用Higher Rank Trait Bounds :特別告訴編譯器此生命周期對使用for<'a>表示法的所有(相關)生命周期有效。 代碼將如下所示:

impl<T: for<'de> Deserialize<'de>> InputCoercible for T {
    // ...trait methods...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM