rea*_*lli 12 lifetime rust 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()
}
Run Code Online (Sandbox Code Playgroud)
当我编译时,我得到了这个:
error[E0106]: missing lifetime specifier
--> src/main.rs:6:23
|
6 | fn from_base64_str<T: Deserialize>(string: &str) -> T {
| ^^^^^^^^^^^ expected lifetime parameter
Run Code Online (Sandbox Code Playgroud)
检查serde doc,Deserialize定义为:
pub trait Deserialize<'de>: Sized {
Run Code Online (Sandbox Code Playgroud)
所以我添加了生命周期:
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()
}
Run Code Online (Sandbox Code Playgroud)
然后编译器告诉我:
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
Run Code Online (Sandbox Code Playgroud)
我只知道Rust中生命周期的基础知识,所以我对'dein 很困惑trait Deserialize.
如何修复此类功能中的生命周期错误?我正在使用Rust 1.18.0-nightly(452bf0852 2017-04-19)
Serde网站的这一部分Deserialize详细介绍了界限.
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特征等同于更高等级的特质界限 for<'de> Deserialize<'de>.唯一的区别是DeserializeOwned阅读更直观.这意味着T拥有所有反序列化的数据.