为什么我可以使用 if 比较字符串与 &str,但使用 match 时却不行?

问题描述 投票:0回答:2

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

当我与

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`

我已经看到了如何将字符串与 Rust 中的字符串文字进行匹配?所以我知道如何解决它,但我想知道为什么

if
但不使用
match
时比较有效。

string rust match literals
2个回答
79
投票

我想知道为什么比较在

if
时有效但不使用
match

这与

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

==
运算符实际上是与
PartialEq
特征
相关的函数。此特征可以针对任何“pair”类型实现。而且,为了方便起见,String 还实现了
PartialEq<str>
PartialEq<&str>
等 - 反之亦然。

另一方面,

match

表达式使用

模式匹配
进行比较,而不是==
&'static str
文字,如
"holla!"
,是有效模式,但它永远不能匹配
String
,这是完全不同的类型。

模式匹配可以让您简洁地比较复杂结构的各个部分,即使整个结构不相等,也可以将变量绑定到匹配的各个部分。虽然

String

并没有真正从中受益,但它对于其他类型来说非常强大,并且具有与

==
完全不同的目的。

请注意,您可以通过使用

if

构造来使用与

if let
的模式匹配。你的例子看起来像这样:

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") }



19
投票

有一个奇妙的方法

String::as_str()

可以做到这一点:

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

旧答案

正如 @peter-hall 所说,存在类型不匹配,因为

match

表达式使用模式匹配,这与与

==
特征相关的
PartialEq
不同。
还有第二种方法可以解决此问题,即将 

String

转换为

&str
(字符串切片):
match &s[..] {
    "holla!" => println!("it worked!"),
    "Hallo!" => println!("with easy to read matches !"),
    _ => println!("nothing"),
}

© www.soinside.com 2019 - 2024. All rights reserved.