0Pricing
Elixir & Phoenix: Scalable Backend Development · درس

مطابقة الأنماط وتدفق التحكم

أتقنوا ميزة مطابقة الأنماط القوية في Elixir وتراكيب تدفق التحكم الأساسية مثل `if` و`case` و`cond`.

مطابقة الأنماط وتدفق التحكم درس مجاني في Elixir & Phoenix: Scalable Backend Development على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Elixir & Phoenix: Scalable Backend Development، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Elixir & Phoenix: Scalable Backend Development 4 دروس في المجموع.

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

Intro to Pattern Matching

Pattern matching is the heart of Elixir. Here = is a match operator, not assignment — it makes the left side equal the right.

Basic Variable Matching

The simplest match binds an unbound variable to a value. If it is already bound, Elixir instead checks that the two sides actually match.

defmodule BasicMatchDemo do
  def run do
    # 'a' is unbound, so it's assigned 10
    a = 10
    IO.puts "a is: #{a}"

    # 'b' is unbound, so it's assigned 20
    b = 20
    IO.puts "b is: #{b}"

    # This matches 'a' to the value of 'b' (20)
    # 'a' is re-bound to 20
    a = b
    IO.puts "After a = b, a is: #{a}"
  end
end

BasicMatchDemo.run()

Matching with Literals

Put a literal on the left and the match becomes an assertion: it succeeds only if both sides are equal, otherwise it raises. Handy for validation.

defmodule LiteralMatchDemo do
  def run do
    # This matches because 1 is equal to 1
    1 = 1
    IO.puts "1 = 1 matched successfully!"

    # This matches because 'hello' is equal to 'hello'
    "hello" = "hello"
    IO.puts "'hello' = 'hello' matched successfully!"

    # If you uncomment the line below, it will cause a MatchError
    # 1 = 2
    # IO.puts "This line would not be reached if 1 = 2 failed"
  end
end

LiteralMatchDemo.run()

Deconstructing Tuples

Matching shines on tuples — deconstruct them straight into variables, which is exactly how you unpack {:ok, value} results.

defmodule TupleMatchDemo do
  def run do
    # Match a tuple to extract its elements
    {:person, name, age} = {:person, "Alice", 30}
    IO.puts "Name: #{name}, Age: #{age}"

    # Match a common result tuple
    {:ok, data} = {:ok, "User fetched successfully"}
    IO.puts "Status: ok, Data: #{data}"

    # If you uncomment the line below, it will cause a MatchError
    # {:error, reason} = {:ok, "Success"}
  end
end

TupleMatchDemo.run()

Deconstructing Lists

Deconstruct lists with the [head | tail] pattern: head is the first element, tail the rest. Use _ for parts you do not care about.

defmodule ListMatchDemo do
  def run do
    list = [1, 2, 3, 4, 5]

    # Match head and tail
    [head | tail] = list
    IO.puts "Head: #{head}, Tail: #{inspect tail}"

    # Match specific elements
    [first, second, third | _rest] = list
    IO.puts "First: #{first}, Second: #{second}, Third: #{third}"

    # Match an empty list
    [] = []
    IO.puts "Empty list matched!"
  end
end

ListMatchDemo.run()

The Pin Operator (^)

The pin operator ^ says "do not rebind — match against this variable's current value" instead. Great for asserting equality.

defmodule PinOperatorDemo do
  def run do
    value_a = 10
    value_b = 10

    # This uses the current value of value_a (10) to match against value_b
    # It succeeds because 10 matches 10
    ^value_a = value_b
    IO.puts "Match successful: value_a = #{value_a}, value_b = #{value_b}"

    value_c = 5

    # If you uncomment the line below, it will cause a MatchError
    # because ^value_a (10) is not equal to value_c (5)
    # ^value_a = value_c
    # IO.puts "This line would not be reached if ^value_a = value_c failed"
  end
end

PinOperatorDemo.run()

Simple Conditionals: if/unless

For simple branches use if and its mirror unless, each with an optional else. The cleanest tool for one true/false condition.

defmodule IfUnlessDemo do
  def run do
    number = 7

    if number > 5 do
      IO.puts "Number is greater than 5"
    else
      IO.puts "Number is 5 or less"
    end

    unless rem(number, 2) == 0 do
      IO.puts "Number is odd"
    else
      IO.puts "Number is even"
    end
  end
end

IfUnlessDemo.run()

Handling Multiple Patterns with case

The case expression matches one value against several patterns and runs the first that fits — pattern matching as control flow.

defmodule CaseExpressionDemo do
  def run do
    status = {:ok, "Data loaded"}

    case status do
      {:ok, message} ->
        IO.puts "Success: #{message}"
      {:error, reason} ->
        IO.puts "Failed: #{reason}"
      _ ->
        IO.puts "Unknown status"
    end

    # Another example with a simple value
    grade = "B"
    case grade do
      "A" -> IO.puts "Excellent!"
      "B" -> IO.puts "Good job!"
      _ -> IO.puts "Keep trying!"
    end
  end
end

CaseExpressionDemo.run()

Multiple Conditions with cond

When you have many boolean checks (an if/else-if chain elsewhere), cond runs the first clause whose condition is true.

defmodule CondExpressionDemo do
  def run do
    score = 85

    cond do
      score >= 90 -> IO.puts "Grade: A"
      score >= 80 -> IO.puts "Grade: B"
      score >= 70 -> IO.puts "Grade: C"
      true -> IO.puts "Grade: D or lower" # The 'true' clause acts as a catch-all
    end

    temperature = 25
    cond do
      temperature > 30 -> IO.puts "It's hot!"
      temperature > 20 -> IO.puts "It's warm."
      true -> IO.puts "It's cool."
    end
  end
end

CondExpressionDemo.run()

Pattern Matching Challenge

Consider the following Elixir code snippet:

data = ["apple", {:fruit, "banana"}, "cherry"]
[first, {:fruit, second}, _] = data

What will be the final values of the variables first and second after this code executes?

Recap: Pattern Matching & Control

Recap: = matches, you deconstruct tuples and lists, ^ pins a value, and if/case/cond drive your control flow.

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

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

نعم — نص درس «مطابقة الأنماط وتدفق التحكم» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Elixir & Phoenix: Scalable Backend Development، انتقل إلى CoddyKit PRO. تتضمن دورة Elixir & Phoenix: Scalable Backend Development 4 دروس في المجموع.

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

أتقنوا ميزة مطابقة الأنماط القوية في Elixir وتراكيب تدفق التحكم الأساسية مثل `if` و`case` و`cond`. تتمرن على Elixir & Phoenix: Scalable Backend Development مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Elixir & Phoenix: Scalable Backend Development؟

لا تُشترط خبرة سابقة. Elixir & Phoenix: Scalable Backend Development على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

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

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

هل يمكنني كتابة وتشغيل أكواد في درس Elixir & Phoenix: Scalable Backend Development هذا؟

نعم. كل درس في Elixir & Phoenix: Scalable Backend Development يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

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

  1. مقدمة إلى لغة Elixir
  2. أنواع البيانات والعوامل الأساسية
  3. مطابقة الأنماط وتدفق التحكم
  4. السلاسل والثنائيات والرموز Sigils في Elixir
← العودة إلى Elixir & Phoenix: Scalable Backend Development