حارس المطابقة (match guard)
شرط if إضافي بعد النمط، يُقبَل الفرع فقط إن تحقّق أيضًا:
let num = Some(4);
match num {
Some(x) if x % 2 == 0 => println!("{x} زوجي"),
Some(x) => println!("{x} فردي"),
None => {}
}
⚠️ الحارس لا يُحسب ضمن فحص الشمولية — لازم تبقى تغطّي كل الاحتمالات بفرع افتراضي
_أو ما شابه، وإلا لن يُترجم الكود.
الربط باسم مع @
يتيح لك اختبار قيمة مقابل نطاق و تسميتها بنفس الوقت:
enum Message {
Hello { id: i32 },
}
let msg = Message::Hello { id: 5 };
match msg {
Message::Hello { id: id @ 3..=7 } => {
println!("معرّف ضمن النطاق: {id}")
}
Message::Hello { id } => println!("معرّف آخر: {id}"),
}
بدون @ كنت ستعرف أن id بين 3 و7، لكن دون أن تملك قيمته الفعلية داخل الفرع.
تفكيك الهياكل والصفوف
struct Point { x: i32, y: i32 }
let p = Point { x: 0, y: 7 };
match p {
Point { x, y: 0 } => println!("على محور x عند {x}"),
Point { x: 0, y } => println!("على محور y عند {y}"),
Point { x, y } => println!("نقطة عامّة: ({x}, {y})"),
}
// تجاهل باقي الحقول بـ ..
match p {
Point { x, .. } => println!("x فقط: {x}"),
}
نطاقات وأنماط متعدّدة بـ |
let x = 5;
match x {
1..=5 => println!("بين 1 و5"),
_ => println!("غير ذلك"),
}
match x {
1 | 2 | 3 => println!("واحد من ثلاثة"),
_ => println!("غير ذلك"),
}
💡
..=شامل للطرفين، ويعمل مع الأعداد والحروف ('a'..='j') لكن ليس مع النصوص أو الأنواع المركّبة.
🎯 التالي: Rust غير الآمنة (Unsafe Rust).