Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

الأنماط والمطابقة (Patterns & Matching - 3.0)

جزء من قسم Object Oriented Programming في رحلة Dart على Coddy — الدرس 87 من 110.

قدمت Dart 3 مطابقة الأنماط (pattern matching)، وهي طريقة قوية لتفكيك البيانات وفحصها في تعبير واحد. تتيح لك الأنماط استخراج القيم من الكائنات، والتحقق من بنيتها، وربط المتغيرات - كل ذلك في آن واحد.

لقد رأيت بالفعل التفكيك الأساسي مع السجلات. تعمل الأنماط على توسيع ذلك ليشمل الكائنات والقوائم والخرائط:

void main() {
  // أنماط القوائم
  var numbers = [1, 2, 3];
  var [a, b, c] = numbers;
  print('$a, $b, $c');  // 1, 2, 3
  
  // أنماط الخرائط
  var user = {'name': 'Alice', 'age': 30};
  var {'name': name, 'age': age} = user;
  print('$name is $age');  // Alice is 30
}

تصبح الأنماط (Patterns) قوية بشكل خاص في تعبيرات switch. يمكنك المطابقة بناءً على النوع والقيمة والبنية في آنٍ واحد:

String describe(Object obj) {
  return switch (obj) {
    int n when n < 0 => 'Negative number',
    int n => 'Positive number: $n',
    String s => 'String of length ${s.length}',
    [int first, ...] => 'List starting with $first',
    _ => 'Something else',
  };
}

void main() {
  print(describe(-5));        // رقم سالب
  print(describe(42));        // رقم موجب: 42
  print(describe([1, 2, 3])); // قائمة تبدأ بـ 1
}

تضيف جملة when شروطاً إلى الأنماط، وتطابق ... العناصر المتبقية في القائمة. تعمل الشرطة السفلية _ كرمز بديل يطابق أي شيء. وبالاقتران مع الأصناف المختومة (sealed classes)، تتيح الأنماط معالجة شاملة وآمنة للأنواع (type-safe) لهياكل البيانات المعقدة.

challenge icon

التحدي

سهل

لنقم ببناء مصنف بيانات يستخدم مطابقة الأنماط (pattern matching) لتحليل وتصنيف أنواع مختلفة من المدخلات! ستقوم بإنشاء نظام يمكنه تحديد ووصف هياكل البيانات المختلفة باستخدام ميزات مطابقة الأنماط القوية في Dart 3.

ستقوم بتنظيم الكود الخاص بك في ملفين:

  • classifier.dart: أنشئ دالة تسمى classify تأخذ معاملًا من نوع Object وتعيد وصفًا من نوع String. استخدم تعبير switch مع مطابقة الأنماط للتعامل مع هذه الحالات:
    • القائمة الفارغة [] يجب أن تعيد Empty list
    • القائمة التي تحتوي على عنصر صحيح واحد بالضبط يجب أن تعيد Single item: [value]
    • القائمة التي تحتوي على عنصرين بالضبط يجب أن تعيد Pair: [first] and [second]
    • القائمة التي تبدأ بعدد صحيح متبوعًا بعناصر أخرى يجب أن تعيد List starting with [first], length: [total length] (استخدم نمط البقية ...)
    • الخريطة (map) التي تحتوي على المفتاحين 'name' و 'age' يجب أن تعيد [name] is [age] years old (استخدم تفكيك نمط الخريطة)
    • العدد الصحيح السالب (استخدم بند when) يجب أن يعيد Negative: [value]
    • العدد الصحيح الذي يساوي صفرًا يجب أن يعيد Zero
    • أي عدد صحيح آخر يجب أن يعيد Positive: [value]
    • أي قيمة أخرى يجب أن تعيد Unknown type
  • main.dart: استورد المصنف الخاص بك واستعرض مطابقة الأنماط مع مدخلات متنوعة. اطبع نتيجة تصنيف كل من هذه القيم:
    • قائمة فارغة []
    • قائمة تحتوي على عنصر واحد: [42]
    • قائمة تحتوي على عنصرين: ['hello', 'world']
    • قائمة أطول: [1, 2, 3, 4, 5]
    • خريطة: {'name': 'Alice', 'age': 25}
    • العدد الصحيح -10
    • العدد الصحيح 0
    • العدد الصحيح 99

يجمع هذا التحدي بين أنماط القوائم، وأنماط الخرائط، وبند when للحماية، ونمط البقية (...) - وهي جميع ميزات مطابقة الأنماط الرئيسية من الدرس!

المخرجات المتوقعة:

Empty list
Single item: 42
Pair: hello and world
List starting with 1, length: 5
Alice is 25 years old
Negative: -10
Zero
Positive: 99

ورقة مرجعية

قدمت Dart 3 مطابقة الأنماط (pattern matching) لتفكيك البيانات وفحصها في تعبير واحد.

أنماط القوائم (List Patterns)

استخراج القيم من القوائم:

var numbers = [1, 2, 3];
var [a, b, c] = numbers;
print('$a, $b, $c');  // 1, 2, 3

أنماط الخرائط (Map Patterns)

تفكيك الخرائط حسب المفتاح:

var user = {'name': 'Alice', 'age': 30};
var {'name': name, 'age': age} = user;
print('$name is $age');  // Alice is 30

تعبيرات Switch مع الأنماط

المطابقة بناءً على النوع، القيمة، والبنية:

String describe(Object obj) {
  return switch (obj) {
    int n when n < 0 => 'Negative number',
    int n => 'Positive number: $n',
    String s => 'String of length ${s.length}',
    [int first, ...] => 'List starting with $first',
    _ => 'Something else',
  };
}

ميزات الأنماط

  • بند when: يضيف شروطاً للأنماط
  • ... (نمط البقية): يطابق العناصر المتبقية في القائمة
  • _ (العنصر النائب): يطابق أي شيء

جرّب بنفسك

import 'classifier.dart';

void main() {
  // TODO: استخدم الدالة classify لتصنيف كل قيمة
  // وطباعة النتائج
  
  // اختبار مع قائمة فارغة
  print(classify([]));
  
  // TODO: اختبار مع قائمة تحتوي على عنصر واحد: [42]
  
  // TODO: اختبار مع قائمة تحتوي على عنصرين: ['hello', 'world']
  
  // TODO: اختبار مع قائمة أطول: [1, 2, 3, 4, 5]
  
  // TODO: اختبار مع map: {'name': 'Alice', 'age': 25}
  
  // TODO: اختبار مع العدد الصحيح -10
  
  // TODO: اختبار مع العدد الصحيح 0
  
  // TODO: اختبار مع العدد الصحيح 99
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming