34、match(模式匹配)
match
(模式匹配)
枚举类型比较常用的应用场景是用match
语句来进行模式匹配。
enum Status {
ToDo,
InProgress,
Done
}
impl Status {
fn is_done(&self) -> bool {
match self {
Status::Done => true,
// The `|` operator lets you match multiple patterns.
// It reads as "either `Status::ToDo` or `Status::InProgress`".
Status::InProgress | Status::ToDo => false
}
}
}
match
语句可以让我们将Rust值与一系列模式进行比较。
可以把它看作是类型级别的if
语句。在上面的代码中,如果status
是Done
这个枚举变体,就执行第一个代码块,如果status
是InProgress
枚举变体或ToDo
枚举变体,则执行第二个代码块。
详尽性
这里有一个关键的细节:match
是详尽的。我们必须处理所有的枚举变体。
如果我们忘记了处理某个枚举变体,那么Rust会在拒绝编译代码。
比如,如果我们忘记处理ToDo
变体:
match self {
Status::Done => true,
Status::InProgress => false,
}
编译器会报错:
error[E0004]: non-exhaustive patterns: `ToDo` not covered
--> src/main.rs:5:9
|
5 | match status {
| ^^^^^^^^^^^^ pattern `ToDo` not covered
全部匹配
如果我们不关心其中的一个或多个变体,可以使用_
模式来实现全部匹配:
match status {
Status::Done => true,
_ => false
}
_
匹配会匹配前面的模式没有匹配到的变体。
通过使用这种通配模式,我们将无法享受到编译器驱动重构的优势。如果我们添加了一个新的枚举变体,编译器将不会提示我们未处理该变体。
为了确保很高的正确性,安全性,可以尽量避免使用_
。
练习
实现一个n_sides
方法,可以根据Shape
枚举变体的边数输出对应的边
题目:
pub enum Shape {
Circle,
Square,
Rectangle,
Triangle,
Pentagon,
}
impl Shape {
// TODO: Implement the `n_sides` method using a `match`.
pub fn n_sides(&self) -> u8 {
/* TODO */ }
}
答案:
use crate::Shape::{Circle, Square};
pub enum Shape {
Circle,
Square,
Rectangle,
Triangle,
Pentagon,
}
impl Shape {
// TODO: Implement the `n_sides` method using a `match`.
pub fn n_sides(&self) -> u8 {
match &self {
Shape::Circle => 0,
Shape::Square => 4,
Shape::Rectangle => 4,
Shape::Triangle => 3,
Shape::Pentagon => 5,
}
}
}
这一节的学习就先到这了。
阅读剩余
版权声明:
作者:CN059
链接:https://www.cn059.com/2025/09/16/34%e3%80%81match%ef%bc%88%e6%a8%a1%e5%bc%8f%e5%8c%b9%e9%85%8d%ef%bc%89.html
文章版权归作者所有,未经允许请勿转载。
THE END