2017-04-22 1 views
9

Ich verwende serde und serde_json 1.0 Daten aus einer Base64 Zeichenfolge zu entschlüsseln:Lebensdauer Fehler beim Erstellen einer Funktion, die einen Wert der Umsetzung serde zurück :: Deserialize

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

Wenn ich kompilieren, ich habe diese:

pub trait Deserialize<'de>: Sized { 

Also habe ich ein:

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

die serde doc Überprüfung wird Deserialize definiert die Lebensdauer 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() 
} 

Der Compiler sagte mir dann:

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 

Ich kenne nur die Grundlagen von Leben in Rust, so dass ich von den 'de in trait Deserialize sehr verwirrt.

Wie kann ich den Lebenszeitfehler in einer solchen Funktion beheben? Ich verwende Rust 1.18.0-nächtliche (452bf0852 2017-04-19)

Antwort

6

ich eine Antwort von Serde issue 891 gefunden: Ich DeserializeOwned statt Deserialize verwenden sollte.

4

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


Es gibt zwei Möglichkeiten, Deserialize Charakterzug Grenzen zu schreiben, sei es auf einem impl Block oder eine Funktion oder anderswo.

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

    Das bedeutet, "T von einige Lebensdauer deserialisiert werden kann." Der Anrufer muss entscheiden, welche Lebensdauer das ist. In der Regel wird dies verwendet, wenn der Aufrufer auch die Daten bereitstellt, von denen deserialisiert wird, z. B. in einer Funktion wie serde_json::from_str. In diesem Fall müssen die Eingabedaten ebenfalls eine Lebensdauer von 'de haben, z. B. &'de str.

  • <T> where T: DeserializeOwned

    Das bedeutet, "T kann von jede Lebensdauer deserialisiert werden." Der Angerufene muss entscheiden, wie lange er lebt. Normalerweise liegt das daran, dass die Daten, von denen deserialisiert wird, weggeworfen werden, bevor die Funktion zurückkehrt, so dass T nicht berechtigt sein darf, von ihm zu borgen. Zum Beispiel eine Funktion, die base64-codierte Daten als Eingabe akzeptiert, sie von base64 dekodiert, einen Wert vom Typ T deserialisiert und dann das Ergebnis der base64-Decodierung verwirft. Eine weitere häufige Verwendung dieser Begrenzung sind Funktionen, die aus einem IO-Stream deserialisieren, z. B. serde_json::from_reader.

    Um es technisch zu sagen, das DeserializeOwned Merkmal entspricht dem higher-rank trait boundfor<'de> Deserialize<'de>. Der einzige Unterschied ist DeserializeOwned ist intuitiver zu lesen. Das bedeutet, T besitzt alle Daten, die deserialisiert werden.

Verwandte Themen