2017-04-22 56 views
9
函数时

我使用SERDE和serde_json 1.0从一个base64字符串数据进行解码:终身错误创建一个返回值实现SERDE ::反序列化

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 DOC,Deserialize被定义为:

pub trait Deserialize<'de>: Sized { 

所以我一dded寿命:

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 

我只知道在鲁斯特的寿命非常基本的,所以我非常受'detrait Deserialize混淆。

我该如何解决这种功能中的生存期错误?我使用锈1.18.0-每晚(452bf0852 2017-04-19)

回答

4

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


有写Deserialize特质界限,无论是IMPL块或功能或其他地方上有两种途径。

  • <'de, T> where T: Deserialize<'de>

    这意味着 “T可以从一些寿命被反序列化。”来电者可以决定是什么时间。通常当调用者还提供正在被反序列化的数据时,例如在诸如serde_json::from_str之类的函数中使用。在这种情况下,输入数据也必须具有使用期限'de,例如它可能是&'de str

  • <T> where T: DeserializeOwned

    这意味着 “T可以从任何寿命被反序列化。”被调用者可以决定什么时间。通常这是因为正在被反序列化的数据将在函数返回之前被抛弃,所以T不能从中借用。例如,一个接受base64编码数据作为输入的函数,从base64解码它,对T类型的值进行反序列化,然后丢弃base64解码的结果。此绑定的另一个常见用途是从IO流反序列化的函数,如serde_json::from_reader

    从技术上讲,DeserializeOwned的性状相当于higher-rank trait boundfor<'de> Deserialize<'de>。唯一的区别是DeserializeOwned更直观。这意味着T拥有所有被反序列化的数据。