简体   繁体   English

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

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

I'm trying to implement a function that reads command line arguments and compares them to hard-coded string literals.我正在尝试实现一个函数,该函数读取命令行参数并将它们与硬编码的字符串文字进行比较。

When I do the comparison with an if statement it works like a charm:当我与if语句进行比较时,它就像一个魅力:

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

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

But using a match statement (which I guess would be more elegant):但是使用match语句(我想这会更优雅):

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

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

I keep getting an error from the compiler that a String was expected but a &static str was found:我不断从编译器那里收到一个错误,提示是一个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`

I've seen How to match a String against string literals in Rust?我已经看过如何在 Rust 中将字符串与字符串文字进行匹配? so I know how to fix it, but I want to know why the comparison works when if but not using match .所以我知道如何修复它,但我想知道为什么if但不使用match时比较有效。

I want to know why the comparison works when if but not using match .我想知道为什么在if但不使用match时比较有效。

It's not so much about if and more because you've used == in the condition.这与if和 more 无关,因为您在条件中使用了== The condition in an if statement is any expression of type bool ; if语句中的条件是bool类型的任何表达式; you just happen to have chosen to use == there.你只是碰巧选择在那里使用==

The == operator is really a function associated with the PartialEq trait . ==运算符实际上是一个与PartialEq trait相关的函数。 This trait can be implemented for any pair of types.可以为任何类型实现此特征。 And, for convenience, String has implementations for PartialEq<str> and PartialEq<&str> , among others - and vice versa.而且,为了方便起见, StringPartialEq<str>PartialEq<&str>等的实现——反之亦然。

On the other hand, match expressions use pattern matching for comparison, not == .另一方面, match表达式使用模式匹配进行比较,而不是== A &'static str literal, like "holla!"一个&'static str文字,比如"holla!" , is a valid pattern, but it can never match a String , which is a completely different type. , 是一个有效的模式,但它永远无法匹配String ,后者是一种完全不同的类型。

Pattern matching lets you concisely compare parts of complex structures, even if the whole thing isn't equal, as well as bind variables to pieces of the match.模式匹配让您可以简洁地比较复杂结构的各个部分,即使整个结构不相等,也可以将变量绑定到匹配的部分。 While String s don't really benefit from that, it's very powerful for other types, and has an entirely different purpose than == .虽然String并没有真正从中受益,但它对于其他类型非常强大,并且具有与==完全不同的目的。

Note that you can use pattern matching with if by instead using the if let construct.请注意,您可以使用if by 模式匹配,而不是使用if let构造。 Your example would look like this:您的示例如下所示:

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

Conversely, one way to use == inside a match is like this:相反,在match使用==一种方法是这样的:

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

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

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

As @peter-hall said, there's a mismatch of types because match expressions use pattern matching, which is different from the == that are associated with the PartialEq trait.正如@peter-hall 所说,存在类型不匹配,因为match表达式使用模式匹配,这与与PartialEq特征关联的==不同。

There a second way to resolve this issue, by casting your String into an &str (a string slice) :有第二种方法可以解决此问题,将String转换为&str (字符串切片):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM