[英]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.