我正在尝试实现一个读取命令行参数并将它们与硬编码字符串文字进行比较的函数。
当我与
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
时比较有效。
我想知道为什么比较在
时有效但不使用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")
}
String::as_str()
可以做到这一点:
match s.as_str() {
"holla!" => println!("it worked!"),
"Hallo!" => println!("with easy to read matches !"),
_ => println!("nothing"),
}
旧答案match
表达式使用模式匹配,这与与
==
特征相关的 PartialEq
不同。还有第二种方法可以解决此问题,即将 String
转换为
&str
(字符串切片):match &s[..] {
"holla!" => println!("it worked!"),
"Hallo!" => println!("with easy to read matches !"),
_ => println!("nothing"),
}