ChatGPT解决这个技术问题 Extra ChatGPT

如何将字符串与字符串文字匹配?

我试图弄清楚如何在 Rust 中匹配 String

我最初尝试像这样匹配,但我发现 Rust 不能从 std::string::String 隐式转换为 &str

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

这有错误:

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`

然后我尝试构造新的 String 对象,因为我找不到将 String 转换为 &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"),
    }
}

这给了我3次以下错误:

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

如何在 Rust 中实际匹配 String

stringthing.as_str() 可能是所有答案中最直接的;我不喜欢 as_ref,因为它过于笼统,可能导致错误,而且不那么明确,as_ref() 将成为 &str 并不完全清楚,as_str 简单明了.
@Zorf你是对的。当 as_str 尚不存在时,答案被接受。我改变了接受的答案,但感谢所有回答这个问题的人!

m
mcherm

更新: 像这样使用 .as_str()String 转换为 &str

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

原因 .as_str() 更简洁并强制执行更严格的类型检查。特征 as_ref 是为多种类型实现的,并且它的行为可能会针对类型 String 进行更改,从而导致意外结果。同样,如果输入参数改变类型,当该类型实现特征 as_ref 时编译器不会发出问题信号。

文档建议使用 as_str 以及 https://doc.rust-lang.org/std/string/struct.String.htmlhttps://doc.rust-lang.org/std/primitive.str.html

老答案:

as_slice 已弃用,您现在应该改用特征 std::convert::AsRef

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

请注意,您还必须明确处理包罗万象的情况。


使用 rust 1.4.0 可以使用 trim() 功能。仅使用 as_ref() 与字符串不匹配。
我认为匹配失败是因为 trim() 删除了空格。这对于匹配用户输入非常有用。
它不起作用。如果我从 read_line 获取字符串,它只能匹配 _。
不太了解 rust 如何管理不同类型的字符串,但it seems to work on a basic example
@MaskedMan read_line 读取一行。行以 \n 结束。 .trim_end()(或更准确地说,trim_end_matches('\n'))将为您删除它。
S
Shepmaster

你可以这样做:

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

从 Rust 1.7.0 开始,还有一个 as_str 方法:

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

S
Shepmaster

你也可以做

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

看:

标准::字符串::字符串

std::ops::Deref

解除强制


这实际上与 .as_str() 相同,而且更短。
“.as_str()”实际上比“as &str”多 1 个字符?我错过了什么吗? @amyiris
S
Shepmaster

编者注:此答案适用于 Rust 1.0 之前的版本,不适用于 Rust 1.0

您可以匹配字符串切片。

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

最好使用 .as_ref().as_str(),两者都没有取得所有权。
o
omrihhh

你可以试试:

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

如果您解释 &*stringthing 的含义和作用,它可能会提高您的答案的实用性。
u
u_mulder

您可以通过执行以下操作将 String 转换为 &str

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

r
rujen gelal

在字符串上使用 as_str() 来获取字符串切片

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

如果您从控制台获取输入并希望对其执行匹配,请务必在 as_str() 之后调用 trim() 以从输入中删除转义字符,即 '\n'。如在

match stringthing.as_str().trim() {...}