Bagaimana cara mencocokkan String dengan string literal di Rust?

200

Saya mencoba mencari cara untuk mencocokkan String di Rust.

Saya awalnya mencoba mencocokkan seperti ini, tetapi saya tahu Rust tidak bisa secara implisit dilemparkan dari std::string::Stringke &str.

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

Ini memiliki kesalahan:

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`

Saya kemudian mencoba untuk membangun Stringobjek baru , karena saya tidak dapat menemukan fungsi untuk melemparkan Stringke &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"),
    }
}

Ini memberi saya kesalahan berikut 3 kali:

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

Bagaimana cara mencocokkan Stringdi Rust?

Jeroen
sumber
stringthing.as_str()mungkin jawaban yang paling mudah dari semua jawaban; Saya tidak suka as_refkarena itu tidak perlu umum, yang dapat menyebabkan bug, dan tidak sejelas itu, tidak sepenuhnya jelas apakah as_ref()yang akan menjadi &str, as_strsederhana dan jelas.
Zorf
@ Zorf Anda benar. Jawaban diterima ketika as_strbelum ada. Saya mengubah jawaban yang diterima tetapi berterima kasih kepada semua orang yang menjawab pertanyaan ini!
Jeroen

Jawaban:

72

Anda dapat melakukan sesuatu seperti ini:

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

Ada juga as_strmetode pada Rust 1.7.0:

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

as_slicesudah ditinggalkan, Anda sekarang harus menggunakan sifat std::convert::AsRefsebagai gantinya:

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

Perhatikan bahwa Anda juga harus secara eksplisit menangani kasing semua.

Tijs Maas
sumber
3
menggunakan karat 1.4.0 satu dapat menggunakan trim()fungsi. Hanya menggunakan as_ref()tidak cocok dengan string.
futtetennista
1
Saya pikir pertandingan gagal karena spasi yang trim()dihapus. Ini bagus untuk menunda agar sesuai dengan input pengguna.
Gerard Sexton
1
Itu tidak bekerja. Itu hanya bisa cocok dengan _ jika saya mendapatkan String dari read_line.
Masked Man
Tidak tahu banyak tentang bagaimana karat mengelola berbagai jenis string, tetapi tampaknya bekerja pada contoh dasar .
tforgione
10

Catatan editor: Jawaban ini berkaitan dengan versi Rust sebelum 1.0 dan tidak berfungsi di Rust 1.0

Anda dapat mencocokkan pada irisan string.

match stringthing.as_slice() {
    "a" => println!("0"),
    "b" => println!("1"),
    "c" => println!("2"),
    _ => println!("something else!"),
}
AB
sumber
lebih baik digunakan .as_ref()atau .as_str(), keduanya tidak mengambil kepemilikan.
Abrar Khan
1

Anda dapat mencoba:

fn main() {
    let stringthing = String::from("c");
    match &*stringthing {
        "a" => println!("0"),
        "b" => println!("1"),
        "c" => println!("2"),
        _ => println!("else")
    }
}
omrihhh
sumber
1
Ini mungkin meningkatkan kegunaan jawaban Anda jika Anda menjelaskan apa &*stringthingartinya dan apa artinya.
Seth Difley