Rust 新手程式設計/模式匹配
外觀
我們之前建立了 AngleType 列舉。假設我們想列印一些關於角度的解釋。為了根據遇到的列舉變體來改變這個解釋,我們可以使用 match 語句。例如
fn print_angle_info(points: Points) {
match points.angle_type {
AngleType::Acute => {
println!("This angle is an acute angle; one of less than 90 degrees!");
},
AngleType::Right(axis_aligned) => {
if axis_aligned {
println!("This angle is an axis-aligned right angle, exactly 90 degrees!");
} else {
println!("This angle is a non axis-aligned right angle, exactly 90 degrees!");
}
},
AngleType::Obtuse => {
println!("This angle is an obtuse one. That means it more than 90 degrees, but less than 180.");
},
AngleType::Reflex => {
println!("This angle is a reflex angle. That means it's very large: more than 180 degrees :O");
}
}
}
如果角度型別是每個程式碼塊中描述的型別,那麼我們就進入那個程式碼塊的 {} 中,忽略其他所有 {}。例如,如果我們有一個角度型別為銳角的點,我們只會打印出銳角部分。還要注意,由於直角有一個布林值附加,我們可以使用一個名為 axis_aligned 的變數,該變數被設定為該值的任何值。然後我們可以在 {} 中使用它來列印更多關於角度的資訊。注意,我們匹配列舉的所有變體。這是 match 語句的要求。為了說明這一點,我們可以匹配以下函式中的數字
fn print_specific_number_facts(num: u8) {
match num {
0 => println!("The number representing nothingness"),
2 => println!("The only even prime number!"),
6 => println!("A perfect number"),
}
}
首先要注意,我並沒有在行上新增 {}。這是因為我們只有一個匹配數字後的單行,所以我們可以省略它們,但我們必須在行尾新增逗號。這將無法編譯,因為它不知道如果我們得到一個不是 1、2 或 6 的數字該怎麼辦。如果我們想要它在接收沒有事實的數字時什麼也不做,我們可以明確地說
fn print_specific_number_facts(num: u8) {
match num {
0 => println!("The number representing nothingness"),
2 => println!("The only even prime number!"),
6 => println!("A perfect number"),
_ => {},
}
}
下劃線充當匹配所有,空 {} 表示我們不想在這種情況下執行任何操作。我們也可以在其他地方使用下劃線。還記得上一頁的 is_angle_right 函式嗎?作為參考,這是它之前的程式碼
fn is_angle_right(points: Points) -> bool {
points.angle_type == AngleType::Right
}
這不再有效,因為我們可以有 AngleType::Right(true) 或 AngleType::Right(false)。與其分別匹配這兩個,我們可以把它改為
fn is_angle_right(points: Points) -> bool {
points.angle_type == AngleType::Right(_)
}
此外,如果我們想要檢查只對特定列舉變體執行某些操作並使用內部值(s)。一個方便的方法來描述這種模式是使用 'if let'。
fn print_right_angle(points: Points) {
if let AngleType::Right(axis_aligned) = points.angle_type {
if axis_aligned {
println!("axis aligned right angle");
} else {
println!("non axis aligned right angle");
}
} else {
println!("Some other angle");
}
}
這對描述這種模式非常方便,也很容易閱讀。還有許多其他的列舉和結構模式,以及許多與這些模式匹配的方法,但這些是組織和結構化 Rust 中資料的基本構建塊。