0Pricing
Learn Rust Coding · درس

مطابقة الأنماط القوية

أتقنوا تعبيرات `match` وبنى مطابقة الأنماط الأخرى للتعامل مع متغيرات البيانات بإيجاز وشمول.

مطابقة الأنماط القوية درس مجاني في Learn Rust Coding على CoddyKit. هذا هو الدرس 3 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Learn Rust Coding، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Learn Rust Coding 3 دروس في المجموع.

بعض أجزاء هذا الدرس لم تُترجم بعد وتظهر باللغة الإنجليزية.

Unleashing Pattern Matching

Welcome to the world of pattern matching in Rust! This powerful feature allows you to control program flow based on the structure of data.

Instead of just checking equality, you can deconstruct values, extract components, and execute specific code for different data shapes.

  • It's like a super-powered if/else or switch statement.
  • Ensures exhaustiveness: you must handle all possible patterns.
  • Makes code more readable and robust.

The `match` Expression Basics

The core of pattern matching is the match expression. It takes a value and compares it against a series of patterns. The first pattern that matches wins!

Each 'arm' of a match expression consists of a pattern and the code to execute if that pattern matches.

enum Direction {
  North,
  East,
  South,
  West,
}

fn main() {
  let my_direction = Direction::North;

  match my_direction {
    Direction::North => println!("Going up!"),
    Direction::East => println!("Going right!"),
    Direction::South => println!("Going down!"),
    Direction::West => println!("Going left!"),
  }
}

Matching Literals and Ranges

You can match against specific literal values (numbers, characters, booleans) or define ranges using ..=. The | operator allows matching multiple patterns with a single arm.

Remember, patterns are checked in order, and the first match is used.

fn main() {
  let x = 7;

  match x {
    1 => println!("It's one!"),
    2 | 3 => println!("It's two or three!"),
    4..=8 => println!("It's between four and eight!"),
    _ => println!("It's something else!"), // Catch-all
  }

  let character = 'b';
  match character {
    'a'..='e' => println!("Early letter"),
    _ => println!("Other letter"),
  }
}

Destructuring Structs

Pattern matching really shines when destructuring complex data types like structs. You can extract individual fields directly into variables within the match arm.

This makes accessing struct data clean and concise, especially when matching specific field values.

struct Point {
  x: i32,
  y: i32,
}

fn main() {
  let p = Point { x: 0, y: 7 };

  match p {
    Point { x, y: 0 } => println!("On the X axis at {}", x),
    Point { x: 0, y } => println!("On the Y axis at {}", y),
    Point { x, y } => println!("Not on an axis: ({}, {})", x, y),
  }
}

Destructuring Enums with Data

Enums in Rust can hold associated data. Pattern matching is the primary way to extract this data from an enum variant.

You can destructure the data directly into new variables, making it easy to work with the content of each variant.

enum Message {
  Quit,
  Move { x: i32, y: i32 },
  Write(String),
  ChangeColor(i32, i32, i32),
}

fn process_message(msg: Message) {
  match msg {
    Message::Quit => println!("Quit message."),
    Message::Move { x, y } => {
      println!("Move to x: {}, y: {}", x, y);
    }
    Message::Write(text) => println!("Text message: {}", text),
    Message::ChangeColor(r, g, b) => {
      println!("Color: R:{}, G:{}, B:{}", r, g, b);
    }
  }
}

fn main() {
  process_message(Message::Move { x: 10, y: 20 });
  process_message(Message::Write(String::from("Hello!")));
}

The Wildcard Pattern `_`

The special _ (underscore) pattern acts as a catch-all. It matches any value and does not bind to that value.

It's useful when you need to cover all possibilities for exhaustiveness but don't care about the specific value that matches a particular arm.

fn main() {
  let some_value = Some(5);
  let absent_value: Option<i32> = None;

  match some_value {
    Some(x) => println!("Got a value: {}", x),
    _ => println!("Something else!"), // Matches None too
  }

  match absent_value {
    Some(x) => println!("Got a value: {}", x),
    _ => println!("No value here!"),
  }
}

`if let` for Single Patterns

Sometimes, you only care about matching one specific pattern and want to ignore all others. For these cases, if let is a more concise alternative to a full match expression.

It essentially says: "if this pattern matches, then do this; otherwise, do nothing (or execute an optional else block).".

fn main() {
  let config_max = Some(3u8);
  let none_value: Option<u8> = None;

  if let Some(max) = config_max {
    println!("Max configured to be: {}", max);
  }

  if let Some(val) = none_value {
    println!("This won't print: {}", val);
  } else {
    println!("No value found!");
  }
}

`while let` for Conditional Loops

Similar to if let, while let allows you to loop as long as a pattern continues to match.

This is extremely useful for processing items from collections like Vecs where you want to continue until there are no more matching elements (e.g., until pop() returns None).

fn main() {
  let mut stack = vec![1, 2, 3];

  while let Some(top) = stack.pop() {
    println!("Popped: {}", top);
  }

  println!("Stack is empty now.");
}

Match Guards: Adding Conditions

You can add an additional if condition, called a match guard, to a match arm. The pattern must match AND the guard condition must be true for that arm to execute.

This allows for more fine-grained control within a pattern, without needing to create more enum variants.

fn main() {
  let num = Some(4);

  match num {
    Some(x) if x % 2 == 0 => println!("Even number: {}", x),
    Some(x) if x < 5 => println!("Small odd number: {}", x),
    Some(x) => println!("Any other number: {}", x),
    None => println!("No number"),
  }
}

Pattern Matching Challenge

Consider the following Rust code snippet. Which of the following statements about the match expression and its output are TRUE?

enum Status {
  Loading,
  Success(u32),
  Error(String),
}

fn process_status(s: Status) {
  match s {
    Status::Success(code) if code > 200 => println!("Success with high code: {}", code),
    Status::Success(code) => println!("Success with code: {}", code),
    Status::Error(msg) => println!("Failed: {}", msg),
    _ => println!("Status unknown or loading..."),
  }
}

fn main() {
  process_status(Status::Success(201));
  process_status(Status::Error(String::from("Network issue")));
  process_status(Status::Loading);
  process_status(Status::Success(200));
}

Recap: Mastering Patterns

You've explored the incredible power of pattern matching in Rust! It's a fundamental concept for writing clear, concise, and safe code.

  • match expressions provide exhaustive control flow based on data structure.
  • You can match literals, ranges, and use wildcards (_).
  • Destructuring allows extracting values from structs and enums directly.
  • if let and while let offer concise ways to match single patterns.
  • Match guards add conditional logic to match arms.

Keep practicing these patterns; they're essential for idiomatic Rust!

الأسئلة الشائعة

هل درس «مطابقة الأنماط القوية» مجاني؟

نعم — نص درس «مطابقة الأنماط القوية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Learn Rust Coding، انتقل إلى CoddyKit PRO. تتضمن دورة Learn Rust Coding 3 دروس في المجموع.

ماذا ستتعلم في «مطابقة الأنماط القوية»؟

أتقنوا تعبيرات `match` وبنى مطابقة الأنماط الأخرى للتعامل مع متغيرات البيانات بإيجاز وشمول. تتمرن على Learn Rust Coding مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Learn Rust Coding؟

لا تُشترط خبرة سابقة. Learn Rust Coding على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 3.

كم من الوقت يستغرق درس «مطابقة الأنماط القوية»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Learn Rust Coding هذا؟

نعم. كل درس في Learn Rust Coding يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. تعريف البنى واستخدامها
  2. التعدادات للأنواع المخصّصة
  3. مطابقة الأنماط القوية
← العودة إلى Learn Rust Coding