Come abbinare una stringa a letterali stringa in Rust?


200

Sto cercando di capire come abbinare un Stringin Rust.

Inizialmente ho provato ad abbinare in questo modo, ma ho capito che Rust non può implicitamente lanciare da std::string::Stringa &str.

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

Questo ha l'errore:

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`

Ho quindi cercato di costruire nuovi Stringoggetti, in quanto non riuscivo a trovare una funzione per trasmettere Stringa a &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"),
    }
}

Questo mi ha dato il seguente errore 3 volte:

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

Come abbinare effettivamente Strings in Rust?


stringthing.as_str()è probabilmente la più semplice di tutte le risposte; Non mi piace as_refperché è inutilmente generale, che può portare a bug, e non così esplicito, non è del tutto chiaro che as_ref()sarà un &str, as_strè semplice e chiaro.
Zorf

@Zorf Hai ragione. La risposta è stata accettata quando as_strnon esisteva ancora. Ho cambiato la risposta accettata ma ringrazio tutte le persone che hanno risposto a questa domanda!
Jeroen il

Risposte:


72

Puoi fare qualcosa del genere:

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

C'è anche un as_strmetodo a partire da Rust 1.7.0:

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

190

as_sliceè deprecato, ora dovresti usare std::convert::AsRefinvece il tratto :

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

Nota che devi anche gestire esplicitamente il caso generale.


3
usando la ruggine 1.4.0 si può usare la trim()funzione. Il solo utilizzo as_ref()non corrisponde alla stringa.
futtetennista,

1
Penso che la partita fallisca a causa dello spazio bianco che viene trim()rimosso. Questo è utile perché il rinvio corrisponda all'input dell'utente.
Gerard Sexton,

1
Non funziona Può corrispondere a _ solo se ottengo String da read_line.
Masked Man,

Non so molto su come la ruggine gestisce diversi tipi di stringhe, ma sembra funzionare su un esempio di base .
tforgione,


10

Nota del redattore: questa risposta riguarda una versione di Rust precedente alla 1.0 e non funziona in Rust 1.0

Puoi abbinare una fetta di stringa.

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

meglio usare .as_ref()o .as_str()entrambi non ne hanno preso la proprietà.
Abrar Khan,

1

Puoi provare:

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

1
Potrebbe migliorare l'utilità della tua risposta se spieghi cosa &*stringthingsignifica e cosa fa.
Seth Difley,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.