2015-07-10 25 views
9

Gibt es eine Möglichkeit zu vermeiden, .to_string() aufrufen, wenn ich eine Zeichenfolge brauche? Zum Beispiel:Wie erstelle ich einen String direkt?

fn func1(aaa: String) -> .... 

Und statt

func1("fdsfdsfd".to_string()) 

kann ich so etwas wie dieses:

func1(s"fdsfdsfd") 

Antwort

10

TL; DR:

Ab Rust 1.9, str::to_string, str::to_owned, String::from, str::into alle die gleichen Leistungsmerkmale aufweisen. Verwenden Sie, was Sie bevorzugen.


Die naheliegendste und idiomatische Weg, um eine Zeichenfolge in Scheiben schneiden (&str) zu einem in Besitz genommenen Schnur (String) zu konvertieren ist ToString::to_string zu verwenden. Dies funktioniert für jeden Typ, der Display implementiert. Dies umfasst String-Slices, aber auch ganze Zahlen, IP-Adressen, Pfade, Fehler und so weiter.

Vor Rust 1,9, die Umsetzung der strto_string die formatting infrastructure gehebelt. Während es funktionierte, war es Overkill und nicht der performanteste Weg.

Eine leichtere Lösung war die Verwendung ToOwned::to_owned, die für Typen implementiert ist, die ein "geliehenes" und ein "Eigentum" -Paar haben. Es ist implemented in an efficient manner.

Eine andere leichte Lösung ist die Verwendung Into::into, die From::from nutzt. Dies ist auch implemented efficiently.


Für Ihren spezifischen Fall das Beste, was zu tun ist, ein &str, wie thirtythreeforty answered zu akzeptieren. Dann müssen Sie Zero Allokationen tun, was das beste Ergebnis ist.

Im Allgemeinen werde ich wahrscheinlich into verwenden, wenn ich eine zugewiesene Zeichenfolge erstellen muss - es ist nur 4 Buchstaben lang^_ ^. Wenn ich Fragen zu Stack Overflow beantworte, verwende ich to_owned, da es viel offensichtlicher ist, was passiert.

+0

also welche für "fdsfd" zu verwenden? – imatahi

+0

@imatahi aktualisiert. – Shepmaster

12

Nein, die str::to_string() Methode ist die kanonische Weise eine String von einem &'static str schaffen (ein Zeichenfolgenliteral). Ich mag es sogar aus dem Grund, weil du es nicht magst: es ist ein wenig wortreich. Da es sich um eine Heap-Zuweisung handelt, sollten Sie es sich zweimal überlegen, bevor Sie es in solchen Fällen aufrufen. Beachten Sie auch, dass seit Rust gained impl specialization, str::to_string nicht langsamer als str::to_owned oder seinesgleichen ist.

jedoch, was Sie wirklich hier wollen, ist ein func1, die leicht eine beliebige Zeichenfolge übergeben werden kann, sei es ein &str oder ein String. Da ein String wird Deref zu einem &str, können Sie func1 eine &str akzeptieren, wodurch die String-Zuweisung insgesamt vermieden wird. Sehen Sie dieses Beispiel (playground):

fn func1(s: &str) { 
    println!("{}", s); 
} 

fn main() { 
    let allocated_string: String = "owned string".to_string(); 
    func1("static string"); 
    func1(&allocated_string); 
} 
+2

'to_string' noch standardmäßig verwendet, auch wenn es technisch etwas langsamer ist. Mit Spezialisierung wird es jedoch nicht sein. –

+1

nach alex crichton, 'to_string' ist der idiomatische Weg, um eine' str' zu einer 'String' zu konvertieren: https://github.com/rust-lang/rust/pull/26176 –

+0

@steveklabnik bei diesem GitHub Link, Du hast gesagt, dass "' to_owned() 'besser für generischen Code ist." Warum das? – thirtythreeforty

-1

Ich ziehe jetzt stark to_owned() für Stringliterale über entweder von to_string() oder into().

Was ist der Unterschied zwischen String und &str? Eine unbefriedigende Antwort lautet: "Eine ist eine Zeichenkette und die andere ist keine Zeichenkette", denn offensichtlich sind beide Zeichenketten. Nimmt man etwas, das eine Zeichenkette ist und wandelt es in eine Zeichenkette mit to_string() um, scheint es, als ob es den Punkt vermisst, warum wir das überhaupt machen und, was noch wichtiger ist, die Gelegenheit versäumt, dies unseren Lesern zu dokumentieren.

Der Unterschied zwischen String und & str ist, dass man im Besitz ist und man nicht gehört. Die Verwendung von to_owned() erfasst vollständig, warum eine Konvertierung an einer bestimmten Stelle in unserem Code erforderlich ist.

struct Wrapper { 
    s: String 
} 

// I have a string and I need a string. Why am I doing this again? 
Wrapper { s: "s".to_string() } 

// I have a borrowed string but I need it to be owned. 
Wrapper { s: "s".to_owned() } 

Nicht, wenn Sie geistig gelesen wird to_string als to_String

https://users.rust-lang.org/t/to-string-vs-to-owned-for-string-literals/1441/6?u=rofrol