String 为什么我可以将字符串与a&;进行比较;str使用if,但不使用match?
我正在尝试实现一个函数,该函数读取命令行参数并将它们与硬编码字符串文本进行比较 当我使用String 为什么我可以将字符串与a&;进行比较;str使用if,但不使用match?,string,rust,match,literals,String,Rust,Match,Literals,我正在尝试实现一个函数,该函数读取命令行参数并将它们与硬编码字符串文本进行比较 当我使用if语句进行比较时,它就像一个符咒: fn main() { let s = String::from("holla!"); if s == "holla!" { println!("it worked!"); } } 但是使用match语句(我想这会更优雅): 我不断从编译器中得到一个错误,即预期为字符串,但找到了静态str: 错误[E0308]:类型不匹配 --
if
语句进行比较时,它就像一个符咒:
fn main() {
let s = String::from("holla!");
if s == "holla!" {
println!("it worked!");
}
}
但是使用match
语句(我想这会更优雅):
我不断从编译器中得到一个错误,即预期为字符串
,但找到了静态str
:
错误[E0308]:类型不匹配
-->src/main.rs:5:9
|
5 |“你好!”=>println!(“成功了!”),
|^^^^^^^应为结构'std::string::string',找到引用
|
=注意:应为'std::string::string'类型`
找到类型`&'static str`
我已经看到了,所以我知道如何修复它,但我想知道为什么当if
但不使用match
时比较有效
我想知道为什么当if
但不使用match
时比较有效
这与if
无关,因为您在条件中使用了==
。if
语句中的条件是bool
类型的任何表达式;您恰好选择在那里使用==
==
运算符实际上是与相关联的函数。这个特性可以用于任何一对类型。而且,为了方便起见,String
有PartialEq
和PartialEq
等的实现,反之亦然
另一方面,match
表达式用于比较,而不是=
。&'static str
literal,如“holla!”
,是一种有效的模式,但它永远无法与字符串匹配,后者是一种完全不同的类型
模式匹配允许您简洁地比较复杂结构的各个部分,即使整个结构不相等,也可以将变量绑定到匹配的各个部分。虽然String
s实际上并没有从中受益,但它对其他类型的应用非常强大,并且与=
有着完全不同的用途
请注意,您可以通过使用if
来使用模式匹配,而不是使用if let
构造。您的示例如下所示:
if let "holla!" = &*s {
println!("it worked!");
}
match s {
_ if s == "holla!" => println!("it worked!"),
_ => println!("nothing"),
}
相反,在匹配中使用=
的一种方法如下:
if let "holla!" = &*s {
println!("it worked!");
}
match s {
_ if s == "holla!" => println!("it worked!"),
_ => println!("nothing"),
}
或者,正如@ljedrz所建议的:
match s == "holla!" {
true => println!("it worked!"),
_ => println!("nothing")
}
正如@peter hall所说,类型不匹配是因为match
表达式使用模式匹配,这不同于与PartialEq
特征相关联的=
解决此问题的第二种方法是将字符串
强制转换为&str
(字符串片段):
因为&str
是一个引用,而不是一个值。@Shepmaster谢谢你指出我的错误。您链接的问题与我的问题非常相似,但我想知道为什么它与if
比较有效,而与匹配不起作用。这只是因为编译器处理这两个问题的方式不同。if
语句委托给PartialEq
实现。匹配
在编译器中没有这种特殊处理,因此需要一些帮助。无论如何,这两个构造的编译方式不同,因此我不确定这对编译器的内部是如何工作的。if
条件成为一个简单的分支,而match
在向下编译时(根据LLVM IR)看起来确实有点像一个开关。如果只有两个可能的结果(如第二个示例),那么if else
是一个非常好的构造。