Rust有一个名为match
的构造,在其他语言中看起来与switch
非常相似。但是我观察到match
的一种非常特殊的行为。
let some_u32_value = 3;
match some_u32_value {
_ => (),
3 => println!("three"),
}
match
尊重提及案例/模式的顺序。如果默认(_
)案例位于顶部,为什么不报告错误?它确实发出警告:
warning: unreachable pattern
--> src/main.rs:5:9
|
5 | 3 => println!("three"),
| ^
|
= note: #[warn(unreachable_patterns)] on by default
Java中的类似构造,即switch,不保留任何顺序,因此在其他情况之前使用default
不是错误(忽略行为的下降)。
int x = 0;
switch (x) {
default:
System.out.println("default");
break;
case 0:
System.out.println("Zero");
}
有明确的目的吗?
答案 0 :(得分:4)
无法访问的模式并非严格意义上的错误,我的意思是:它不会阻止编译器理解"代码也不会使代码不安全。
同样,例如,在C
中,您可以返回对局部变量的引用而不会触发错误(至少使用gcc
):
#include <stdio.h>
int* foo() {
int x = 0;
return &x;
}
int main() {
printf("%d", *foo());
return 0;
}
一般情况下,您不应该将警告视为&#34;哦,那只只是警告,我不在乎&#34;。警告是编译器提供的实际有用的建议/信息。
我喜欢warnings中给出的定义:
通常会发出警告,认识到潜在的高风险情况,可能的误解,服务质量下降或即将发生的失败。
因为它有助于理解错误和警告之间的区别:
在这种情况下,match
的最后一个部分是一些死代码,因此编译器会相应地报告它。
答案 1 :(得分:3)
Rust的match
表达式比Java switch
语句强大得多,而且您可以做的不仅仅是匹配数字。
特别是,它支持模式匹配,它允许您根据数据的结构或其包含的值来匹配数据。如果要匹配更复杂的模式,则能够指定顺序非常重要,因为模式可能会重叠。例如:
let value = Some((Some(3), "hello"));
let s = match value {
None => "Nothing there!".to_owned(),
Some((Some(3), _)) => "The number is exactly 3!".to_owned(),
Some((Some(n), _)) if n > 3 => format!("Got a number bigger than 3: {}", n),
Some((None, msg)) => format!("Message with no number: {}", msg),
Some((_, msg)) => format!("Got the message, ignore the rest: {}", msg),
_ => "Anything else?".to_owned()
};
println!("result = {}", s);
这里的最后一个案例实际上是不可能的,因为其他分支涵盖了一切。如果不是您想要的,编译器将发出警告。