¿Cómo hacer coincidir una cadena con literales de cadena en Rust?


201

Estoy tratando de descubrir cómo hacer coincidir un StringRust.

Inicialmente intenté combinar de esta manera, pero descubrí que Rust no puede lanzar implícitamente de std::string::Stringa &str.

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

Esto tiene el error:

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`

Luego traté de construir nuevos Stringobjetos, ya que no pude encontrar una función para convertir 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"),
    }
}

Esto me dio el siguiente error 3 veces:

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

¿Cómo hacer coincidir Strings en Rust?


stringthing.as_str()es probablemente la más directa de todas las respuestas; No me gusta as_refporque es innecesariamente general, lo que puede conducir a errores, y no tan explícito, no está completamente claro que as_ref()va a ser un &str, as_stres simple y claro.
Zorf

@ Zorf Tienes razón. La respuesta fue aceptada cuando as_straún no existía. ¡Cambié la respuesta aceptada pero gracias a todas las personas que respondieron esta pregunta!
Jeroen

Respuestas:


73

Puedes hacer algo como esto:

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

También hay un as_strmétodo a partir de Rust 1.7.0:

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

190

as_sliceestá en desuso, ahora debería usar el rasgo en su std::convert::AsReflugar:

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

Tenga en cuenta que también debe manejar explícitamente el caso general.


3
usando rust 1.4.0 se puede usar la trim()función. Solo usando as_ref()no coincide con la cadena.
futtetennista

1
Creo que la coincidencia falla debido al espacio en blanco que trim()elimina. Esto es bueno para defenderse para que coincida con la entrada del usuario.
Gerard Sexton

1
No funciona Solo puede coincidir con _ si obtengo String de read_line.
Hombre enmascarado

No sé mucho sobre cómo el óxido maneja diferentes tipos de cadenas, pero parece funcionar en un ejemplo básico .
tforgione


10

Nota del editor: esta respuesta pertenece a una versión de Rust anterior a 1.0 y no funciona en Rust 1.0

Puedes combinar en un corte de cuerda.

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

mejor uso .as_ref()o .as_str(), ambos no tomaron posesión.
Abrar Khan

1

Puedes probar:

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

1
Podría mejorar la utilidad de su respuesta si explica qué &*stringthingsignifica y qué hace.
Seth Difley
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.