Wie kann man einen String mit String-Literalen in Rust abgleichen?

199

Ich versuche herauszufinden, wie man einen Stringin Rust zusammenbringt.

Ich habe anfangs versucht, so zu passen, aber ich habe herausgefunden, dass Rust nicht implizit von std::string::Stringbis werfen kann &str.

fn main() {
    let stringthing = String::from("c");
    match stringthing {
        "a" => println!("0"),
        "b" => println!("1"),
        "c" => println!("2"),
    }
}

Dies hat den Fehler:

error[E0308]: mismatched types
 --> src/main.rs:4:9
  |
4 |         "a" => println!("0"),
  |         ^^^ expected struct `std::string::String`, found reference
  |
  = note: expected type `std::string::String`
             found type `&'static str`

Ich habe dann versucht , neu zu konstruieren StringObjekte, da ich keine Funktion werfen einen finden konnte Stringzu ein &str.

fn main() {
    let stringthing = String::from("c");
    match stringthing {
        String::from("a") => println!("0"),
        String::from("b") => println!("1"),
        String::from("c") => println!("2"),
    }
}

Dies gab mir dreimal den folgenden Fehler:

error[E0164]: `String::from` does not name a tuple variant or a tuple struct
 --> src/main.rs:4:9
  |
4 |         String::from("a") => return 0,
  |         ^^^^^^^^^^^^^^^^^ not a tuple variant or struct

Wie passt man eigentlich zu Strings in Rust?

Jeroen
quelle
stringthing.as_str()ist wahrscheinlich die einfachste aller Antworten; Ich mag es nicht, as_refweil es unnötig allgemein ist, was zu Fehlern führen kann, und nicht so explizit, es ist nicht ganz klar, dass as_ref()es ein sein wird &str, as_strist einfach und klar.
Zorf
@ Zorf Du hast recht. Die Antwort wurde angenommen, als sie as_strnoch nicht existierte. Ich habe die akzeptierte Antwort geändert, aber ich danke allen, die diese Frage beantwortet haben!
Jeroen

Antworten:

69

Sie können so etwas tun:

match &stringthing[..] {
    "a" => println!("0"),
    "b" => println!("1"),
    "c" => println!("2"),
    _ => println!("something else!"),
}

as_strAb Rust 1.7.0 gibt es auch eine Methode:

match stringthing.as_str() {
    "a" => println!("0"),
    "b" => println!("1"),
    "c" => println!("2"),
    _ => println!("something else!"),
}
Anonymer Feigling
quelle
188

as_sliceveraltet ist, sollten Sie jetzt std::convert::AsRefstattdessen das Merkmal verwenden:

match stringthing.as_ref() {
    "a" => println!("0"),
    "b" => println!("1"),
    "c" => println!("2"),
    _ => println!("something else!"),
}

Beachten Sie, dass Sie auch den Sammelfall explizit behandeln müssen.

Tijs Maas
quelle
3
Mit Rost 1.4.0 kann man die trim()Funktion nutzen. Nur die Verwendung as_ref()stimmt nicht mit der Zeichenfolge überein.
Futtetennista
1
Ich denke, das Match schlägt aufgrund von Leerzeichen fehl, die trim()entfernt werden. Dies ist gut geeignet, um die Deferenzierung mit Benutzereingaben abzugleichen.
Gerard Sexton
1
Es funktioniert nicht. Es kann nur mit _ übereinstimmen, wenn ich String von read_line erhalte.
Maskierter Mann
Ich weiß nicht viel darüber, wie Rost verschiedene Arten von Saiten handhabt, aber es scheint an einem einfachen Beispiel zu funktionieren .
Tforgione
10

Anmerkung des Herausgebers: Diese Antwort bezieht sich auf eine Version von Rust vor 1.0 und funktioniert nicht in Rust 1.0

Sie können auf einem String-Slice übereinstimmen.

match stringthing.as_slice() {
    "a" => println!("0"),
    "b" => println!("1"),
    "c" => println!("2"),
    _ => println!("something else!"),
}
AB
quelle
besser zu benutzen .as_ref()oder .as_str()beide nicht übernommen.
Abrar Khan
1

Du kannst es versuchen:

fn main() {
    let stringthing = String::from("c");
    match &*stringthing {
        "a" => println!("0"),
        "b" => println!("1"),
        "c" => println!("2"),
        _ => println!("else")
    }
}
omrihhh
quelle
1
Es könnte die Nützlichkeit Ihrer Antwort verbessern, wenn Sie erklären, was &*stringthingbedeutet und tut.
Seth Difley