为什么我可以使用 if 将 String 与 &str 进行比较,但在使用 match 时却不能?

Why can I compare a String to a &str using if, but not when using match?

我正在尝试实现一个读取命令行参数并将它们与硬编码字符串文字进行比较的函数。

当我用 if 语句进行比较时,它就像一个魅力:

fn main() {
    let s = String::from("holla!");

    if s == "holla!" {
        println!("it worked!");
    }
}

但是使用 match 语句(我想这会更优雅):

fn main() {
    let s = String::from("holla!");

    match s {
        "holla!" => println!("it worked!"),
        _ => println!("nothing"),
    }
}

我不断从编译器中收到错误消息,提示应为 String,但发现了 &static str

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

我看过 How to match a String against string literals in Rust? 所以我知道如何修复它,但我想知道 为什么 比较在 if 但不使用时有效match.

I want to know why the comparison works when if but not using match.

if 无关,因为您在条件中使用了 ==if 语句中的条件是 bool 类型的任何表达式;你只是碰巧选择了在那里使用 ==

== 运算符实际上是一个与 the PartialEq trait 关联的函数。可以为任何 类型实现此特征。而且,为了方便起见,StringPartialEq<str>PartialEq<&str> 的实现,反之亦然。

另一方面,match 表达式使用 pattern matching 进行比较,而不是 ==&'static str 文字,如 "holla!",是一个有效的模式,但它永远无法匹配完全不同类型的 String

模式匹配让您可以简洁地比较复杂结构的各个部分,即使整个结构不相等,也可以将变量绑定到匹配的各个部分。虽然 Strings 并没有真正从中受益,但它对其他类型非常强大,并且与 ==.

有着完全不同的目的

请注意,您可以通过使用 if let 构造来使用 if 的模式匹配。您的示例如下所示:

if let "holla!" = &*s {
    println!("it worked!");
}

相反,在 match 中使用 == 的一种方法是这样的:

match s {
    _ if s == "holla!" => println!("it worked!"),
    _ => println!("nothing"),
}

或者,正如@ljedrz 建议的那样:

match s == "holla!" {
    true => println!("it worked!"), 
    _ => println!("nothing")
}

正如@peter-hall 所说,存在类型不匹配,因为 match 表达式使用模式匹配,这不同于与 PartialEq 特征关联的 ==

还有第二种方法可以解决此问题,方法是将您的 String 转换为 &str(字符串切片):

match &s[..] {
    "holla!" => println!("it worked!"),
    "Hallo!" => println!("with easy to read matches !"),
    _ => println!("nothing"),
}