Pattern Matching
match Expression
หัวข้อที่มีชื่อว่า “match Expression”match เปรียบเทียบค่ากับชุด pattern และ execute arm ที่ pattern ตรงกัน ต่างจาก switch ใน C, match ของ Rust เป็น expression — สร้างค่าออกมา — และคอมไพเลอร์ตรวจสอบความครบถ้วน
let x: i32 = 3;let description = match x { 1 => "one", 2 => "two", 3 => "three", _ => "something else",};println!("{}", description); // threePattern _ จับคู่กับค่าใดก็ตามที่คุณยังไม่ได้ระบุ หากไม่มี (และไม่ครอบคลุมทุกกรณี) โค้ดจะไม่ compile
การจับคู่ Enum Variant และการ Bind ข้อมูล
หัวข้อที่มีชื่อว่า “การจับคู่ Enum Variant และการ Bind ข้อมูล”พลังที่แท้จริงของ match มาจากการ destructure enum variant และ bind ข้อมูลของตัวเองกับชื่อ local:
enum Coin { Penny, Quarter(String),}
match coin { Coin::Penny => println!("Penny"), Coin::Quarter(state) => println!("Quarter from {}", state),}ตัวระบุ state ใน Coin::Quarter(state) คือ binding — รับค่า String ที่ variant นั้นพกมา แล้วคุณใช้ค่านั้นได้อย่างอิสระในส่วนของ arm
Range Patterns
หัวข้อที่มีชื่อว่า “Range Patterns”Pattern สามารถจับคู่ช่วงของจำนวนเต็มด้วย ..=:
match score { 90..=100 => "A", 80..=89 => "B", _ => "C or below",}Wildcard _
หัวข้อที่มีชื่อว่า “Wildcard _”_ เป็น catch-all ที่จับคู่กับทุกอย่างโดยไม่ bind วางไว้ท้ายสุด arm ใดๆ หลัง _ จะ unreachable และคอมไพเลอร์จะเตือน
if let — การจับคู่ Variant เดียว
หัวข้อที่มีชื่อว่า “if let — การจับคู่ Variant เดียว”เมื่อคุณสนใจแค่ variant เดียว if let กระชับกว่า match แบบเต็ม:
let temperature = Some(22);if let Some(t) = temperature { println!("Temperature: {}C", t);}นี่ bind t กับค่าภายในหาก pattern ตรงกัน และไม่ทำอะไรกับ None คุณสามารถต่อ else สำหรับกรณีที่ไม่ตรง
Match Guards
หัวข้อที่มีชื่อว่า “Match Guards”Guard คือเงื่อนไข if พิเศษบน match arm ที่จำกัดค่าที่ arm จะรับ:
match number { n if n < 0 => println!("negative: {}", n), 0 => println!("zero"), n => println!("positive: {}", n),}Guard ทำงานหลังจาก structural pattern ตรงกันแล้ว ดังนั้น binding (n) จึงใช้ได้ภายในเงื่อนไข guard
#[derive(Debug)]enum Coin { Penny, Nickel, Dime, Quarter(String),}
fn value_in_cents(coin: &Coin) -> u32 { match coin { Coin::Penny => 1, Coin::Nickel => 5, Coin::Dime => 10, Coin::Quarter(state) => { println!("Quarter from {}!", state); 25 } }}
fn describe_number(n: i32) -> &'static str { match n { 0 => "zero", 1..=9 => "single digit", 10..=99 => "double digit", _ => "large", }}
fn main() { let coins = vec![ Coin::Penny, Coin::Nickel, Coin::Quarter(String::from("Alaska")), Coin::Dime, ];
for coin in &coins { println!("{:?} = {} cents", coin, value_in_cents(coin)); }
for n in [0, 7, 42, 100] { println!("{} is {}", n, describe_number(n)); }
let temperature = Some(22); if let Some(t) = temperature { println!("Temperature: {}C", t); }}Compiling…