2017-01-10 7 views
0

Ich habe diese generische Funktion in meinem Rust Code:generische Funktion Zahlen analysieren nicht mit „FromStr nicht implementiert“

fn test<T>(text: &str) -> T { 
    text.parse::<T>() 
} 

Die Idee ist, dass die Anrufer etwas tun würden, wie

test::<u64>("2313"); 

Aber die Kompilierung schlägt mit dieser Nachricht fehl

Ich habe gerade angefangen, Rust gestern zu lernen, also ist das wahrscheinlich Bly eine sehr grundlegende Frage, die ich nicht gefunden habe, um die Antwort zu finden.

+1

Haben Sie die [Traits Kapitel im Buch Rust] (https lesen: // doc.rust-lang.org/book/traits.html)? Es erklärt die Grundlagen und sollte Ihnen helfen, Ihr Problem zu lösen. –

Antwort

6

Wie die Fehlermeldung muss Tcore::str::FromStr implementieren, um für die parse-Funktion anwendbar zu sein. Die Art Unterschrift von parse ist:

fn parse<F>(&self) -> Result<F, F::Err> where F: FromStr 

, die die Art von F begrenzt (oder in Ihrem Fall T) Sie die FromStr Implementierung verwenden können. Ihr anderes Problem ist der Typ, der von test zurückgegeben wird; Es sollte das gleiche sein wie das von parse - a Result.

Wenn Sie diese Probleme zu beheben, wird Ihre Funktion arbeiten:

use std::str::FromStr; 

fn test<T: FromStr>(text: &str) -> Result<T, T::Err> { 
    text.parse::<T>() 
} 

fn main() { 
    println!("{:?}", test::<u64>("2313")); 
} 

Ok (2313)

3

Wenn Sie einen generischen Typparameter T deklarieren, wissen Sie nichts über diesen Typ. Es könnte sein i32, String, () oder PinkElephant; Nur zwei davon können aus einer Zeichenfolge analysiert werden.

Der Weg, um Typen in Rust zu beschränken, ist durch Merkmalsgrenzen: Wir fordern ausdrücklich ein spezifisches Verhalten vom Typ an. Wie "dieser Typ kann ein beliebiger Typ sein, aber ich möchte zumindest die Möglichkeit, eine Instanz dieses Typs zu klonen" (dies wäre das Merkmal Clone). Sie können (und sollten!) Mehr über das Thema der Merkmale lesen in the dedicated chapter in the Rust book.

Welche Funktion erwarten Sie von Ihrem Typ T? Sie möchten eine Instanz von T aus einer Zeichenfolge mithilfe von str::parse() erstellen. Die Funktionssignatur von parse() ist:

fn parse<F>(&self) -> Result<F, F::Err> 
    where F: FromStr 

Es nimmt auch diesen generischen Parameter F und begrenzt es mit dem Merkmale FromStr. Um also parse(), zu verwenden, muss der Typ-Parameter T auch FromStr implementieren. Ihre Funktion könnte wie folgt aussehen:

use std::str::FromStr; 

fn test<T: FromStr>(text: &str) -> T { 
    text.parse::<T>().expect("string was invalid!") 
} 

Was ist das expect() Sie fragen? Nun ... wir berühren ein anderes Thema hier: Fehlerbehandlung. Es gibt auch eine chapter on that topic in the book, die Sie lesen sollten. Kurz gesagt: Sie müssen irgendwie den Fall behandeln, dass die Zeichenfolge ungültig war (wie "peter", wenn Sie versuchten, eine Ganzzahl zu analysieren). expect() ist wahrscheinlich der falsche Weg hier: es Panik nur (bricht den Thread), wenn das Parsen nicht erfolgreich war.

Denken Sie auch daran, dass es einen Compiler-Fehlerindex gibt, in dem Sie mehr über einen bestimmten Fehler lesen können. Here is the entry für Ihren Fehler E0277.

Verwandte Themen