创建返回实现serde :: Deserialize的值的函数时的生命周期错误

时间:2017-04-22 02:48:18

标签: rust lifetime serde serde-json

我使用serde和serde_json 1.0来解码base64字符串中的数据:

fn from_base64_str<T: Deserialize>(string: &str) -> T {
    let slice = decode_config(string, URL_SAFE).unwrap();     
    serde_json::from_slice(&slice).unwrap()
}

当我编译时,我得到了这个:

error[E0106]: missing lifetime specifier
 --> src/main.rs:6:23
  |
6 | fn from_base64_str<T: Deserialize>(string: &str) -> T {
  |                       ^^^^^^^^^^^ expected lifetime parameter

检查serde文档,Deserialize定义为:

pub trait Deserialize<'de>: Sized {

所以我添加了生命周期:

fn from_base64_str<'de, T: Deserialize<'de>>(string: &str) -> T {
    let slice = decode_config(string, URL_SAFE).unwrap();     
    serde_json::from_slice(&slice).unwrap()
}
然后编译器告诉我:

error: `slice` does not live long enough
  --> src/main.rs:11:29
   |
11 |     serde_json::from_slice(&slice).unwrap()
   |                             ^^^^^ does not live long enough
12 | }
   | - borrowed value only lives until here
   |
note: borrowed value must be valid for the lifetime 'de as defined on the body at 9:64...
  --> src/main.rs:9:65
   |
9  |   fn from_base64_str<'de, T: Deserialize<'de>>(string: &str) -> T {
   |  _________________________________________________________________^ starting here...
10 | |     let slice = decode_config(string, URL_SAFE).unwrap();
11 | |     serde_json::from_slice(&slice).unwrap()
12 | | }
   | |_^ ...ending here

我只知道Rust生命中的基本知识,所以我对'de中的trait Deserialize感到非常困惑。

如何修复此类功能中的生命周期错误?我使用Rust 1.18.0-nightly(452bf0852 2017-04-19)

2 个答案:

答案 0 :(得分:11)

我在Serde issue 891找到了答案:我应该使用DeserializeOwned代替Deserialize

答案 1 :(得分:5)

This section of the Serde website covers Deserialize bounds in detail.

有两种主要的方法来编写<IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^promozione-porta-un-amico$ promo.php [L] </IfModule> 特征边界,无论是在impl块还是函数或其他任何地方。

  • <强> Deserialize

    这意味着&#34; T可以从某些生命周期中反序列化。&#34;调用者可以决定它的生命周期。通常,当调用者还提供正在反序列化的数据时,例如在serde_json::from_str之类的函数中,使用此方法。在这种情况下,输入数据也必须具有生命周期<'de, T> where T: Deserialize<'de>,例如它可以是'de

  • <强> &'de str

    这意味着&#34; T可以从任何生命周期中反序列化。&#34;被调用者可以决定生命周期。通常这是因为正在反序列化的数据将在函数返回之前被丢弃,因此不能允许T从中借用。例如,接受base64编码数据作为输入的函数,从base64解码它,反序列化类型T的值,然后抛弃base64解码的结果。此绑定的另一个常见用途是从IO流反序列化的函数,例如serde_json::from_reader

    从技术角度来说,DeserializeOwned特征等同于higher-rank trait bound <T> where T: DeserializeOwned。唯一的区别是for<'de> Deserialize<'de>更直观易读。这意味着T拥有所有反序列化的数据。