为什么我可以使用if将字符串与&str进行比较,但不能在使用匹配时进行比较?

rob*_*tor 8 string literals match rust

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

当我与一个if陈述进行比较时,它就像一个魅力:

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

    if s == "holla!" {
        println!("it worked!");
    }
}
Run Code Online (Sandbox Code Playgroud)

但是使用一个match声明(我想会更优雅):

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

    match s {
        "holla!" => println!("it worked!"),
        _ => println!("nothing"),
    }
}
Run Code Online (Sandbox Code Playgroud)

我一直从编译器得到一个错误,String但是a &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`
Run Code Online (Sandbox Code Playgroud)

我已经看到如何在Rust中匹配字符串与字符串文字?所以我知道如何解决它,但我想知道为什么比较工作if但不使用match.

Pet*_*all 19

我想知道为什么比较工作if但不使用match.

它不是那么多if,因为你已经习惯==了这种情况.if声明中的条件是任何类型的表达式bool; 你碰巧选择在==那里使用.

==运营商是真正与相关联的功能PartialEq特性.可以针对任何类型的实现该特征.而且,为了方便,String对实现PartialEq<str>PartialEq<&str>等等-反之亦然.

另一方面,match表达式使用模式匹配进行比较,而不是==.甲&'static str文字一样"holla!",是一个有效的模式,但它不可能匹配String,这是一个完全不同的类型.

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

请注意,您可以使用模式匹配与if通过作为替代使用if let结构.您的示例如下所示:

if let "holla!" = &*s {
    println!("it worked!");
}
Run Code Online (Sandbox Code Playgroud)

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

match s {
    _ if s == "holla!" => println!("it worked!"),
    _ => println!("nothing"),
}
Run Code Online (Sandbox Code Playgroud)

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

match s == "holla!" {
    true => println!("it worked!"), 
    _ => println!("nothing")
}
Run Code Online (Sandbox Code Playgroud)


Nei*_*Nei 19

新答案

有一个奇妙的方法String::as_str()可以做到这一点:

match s.as_str() {
    "holla!" => println!("it worked!"),
    "Hallo!" => println!("with easy to read matches !"),
    _ => println!("nothing"),
}
Run Code Online (Sandbox Code Playgroud)

旧答案

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

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

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

  • 最高答案!由于 match 是特殊的,而 String 也是特殊的,我们希望编译器能为我们做到这一点。 (2认同)