التحكم في التدفق: If و Else و Switch
ما هو التحكم في التدفق؟
افتراضياً ينفذ Dart الكود من الأعلى إلى الأسفل سطراً بعد سطر. عبارات التحكم في التدفق تتيح لك تغيير هذا السلوك -- يمكنك اتخاذ قرارات أو تخطي كتل من الكود أو الاختيار بين مسارات مختلفة بناءً على شروط. بدون التحكم في التدفق سيفعل كل برنامج نفس الشيء بالضبط في كل مرة يعمل فيها.
عبارة if
عبارة if هي أداة اتخاذ القرار الأساسية. تنفذ كتلة من الكود فقط عندما يُقيّم الشرط إلى true.
عبارة if الأساسية
void main() {
int temperature = 35;
if (temperature > 30) {
print('الجو حار بالخارج!');
}
// الشرط يجب أن يكون bool -- Dart صارمة
// if (1) { ... } // خطأ! 1 ليس bool
// if ('hello') { ... } // خطأ! String ليس bool
}
{} حتى لعبارات if ذات السطر الواحد. يمنع الأخطاء عندما تضيف المزيد من الأسطر لاحقاً ويجعل الكود أسهل في القراءة.عبارة if-else
عندما تريد فعل شيء إذا كان الشرط صحيحاً وشيء آخر إذا كان خاطئاً استخدم if-else:
if-else
void main() {
int age = 16;
if (age >= 18) {
print('يمكنك التصويت.');
} else {
print('لا يمكنك التصويت بعد.');
}
// المخرجات: لا يمكنك التصويت بعد.
// مثال آخر
double balance = 150.0;
double price = 200.0;
if (balance >= price) {
print('تمت عملية الشراء بنجاح!');
balance -= price;
} else {
print('رصيد غير كافٍ. تحتاج \$${(price - balance).toStringAsFixed(2)} إضافية.');
}
}
سلسلة if-else if-else
عندما يكون لديك شروط متعددة للفحص اربطها بـ else if. يُقيّم Dart كل شرط من الأعلى إلى الأسفل وينفذ أول كتلة شرطها صحيح. إذا لم يتطابق أي منها تعمل كتلة else.
شروط متعددة
void main() {
int score = 78;
String grade;
if (score >= 90) {
grade = 'A';
} else if (score >= 80) {
grade = 'B';
} else if (score >= 70) {
grade = 'C';
} else if (score >= 60) {
grade = 'D';
} else {
grade = 'F';
}
print('الدرجة: \$score، التقدير: \$grade');
// المخرجات: الدرجة: 78، التقدير: C
}
score >= 60 قبل score >= 90 ستحصل درجة 95 على “D” بدلاً من “A” لأن 95 >= 60 صحيح وسيتطابق أولاً.عبارات if المتداخلة
يمكنك وضع عبارات if داخل عبارات if أخرى. هذا مفيد عندما يعتمد قرار ثانٍ على الأول.
شروط متداخلة
void main() {
bool isLoggedIn = true;
String role = 'admin';
if (isLoggedIn) {
if (role == 'admin') {
print('مرحباً مدير! لديك صلاحيات كاملة.');
} else if (role == 'editor') {
print('مرحباً محرر! يمكنك تعديل المحتوى.');
} else {
print('مرحباً! لديك صلاحية قراءة فقط.');
}
} else {
print('الرجاء تسجيل الدخول أولاً.');
}
}
if (isLoggedIn && role == 'admin') غالباً أنظف من if متداخلتين.دمج الشروط
استخدم العوامل المنطقية (&& و || و !) لدمج شروط متعددة في عبارة if واحدة:
شروط معقدة
void main() {
int age = 25;
bool hasLicense = true;
bool hasInsurance = true;
// AND -- جميع الشروط يجب أن تكون صحيحة
if (age >= 18 && hasLicense && hasInsurance) {
print('يمكنك القيادة بشكل قانوني.');
}
// OR -- واحد على الأقل يجب أن يكون صحيحاً
String day = 'Saturday';
if (day == 'Saturday' || day == 'Sunday') {
print('إنها عطلة نهاية الأسبوع!');
}
// NOT -- عكس الشرط
bool isBanned = false;
if (!isBanned) {
print('مرحباً بك في المنصة.');
}
}
العامل الثلاثي (التعبير الشرطي)
لعمليات الإسناد البسيطة بـ if-else يوفر العامل الثلاثي بديلاً مختصراً في سطر واحد:
الثلاثي مقابل if-else
void main() {
int temperature = 25;
// باستخدام if-else (مطول)
String weather;
if (temperature > 30) {
weather = 'حار';
} else {
weather = 'لطيف';
}
// باستخدام الثلاثي (مختصر)
String weather2 = temperature > 30 ? 'حار' : 'لطيف';
print(weather2); // لطيف
}
عبارة switch
عندما تحتاج لمقارنة قيمة واحدة مع عدة تطابقات محتملة switch أنظف من سلسلة طويلة من if-else if. كل case يمثل قيمة محتملة واحدة.
عبارة switch الأساسية
void main() {
String day = 'Wednesday';
switch (day) {
case 'Monday':
print('بداية أسبوع العمل.');
break;
case 'Tuesday':
case 'Wednesday':
case 'Thursday':
print('منتصف الأسبوع.');
break;
case 'Friday':
print('تقريباً عطلة نهاية الأسبوع!');
break;
case 'Saturday':
case 'Sunday':
print('أجواء عطلة نهاية الأسبوع!');
break;
default:
print('يوم غير صالح.');
}
// المخرجات: منتصف الأسبوع.
}
case غير فارغ يجب أن ينتهي بـ break أو return أو continue أو throw. على عكس C أو JavaScript لا يسمح Dart بالسقوط الضمني. لكن الحالات الفارغة (مثل Tuesday و Wednesday أعلاه) تسقط طبيعياً إلى الحالة غير الفارغة التالية.Switch مع أنواع مختلفة
Switch على الأعداد الصحيحة
void main() {
int statusCode = 404;
switch (statusCode) {
case 200:
print('OK - الطلب ناجح');
break;
case 301:
print('تم النقل نهائياً');
break;
case 404:
print('غير موجود');
break;
case 500:
print('خطأ داخلي في الخادم');
break;
default:
print('رمز حالة غير معروف: \$statusCode');
}
// المخرجات: غير موجود
}
تعبيرات Switch (Dart 3+)
قدم Dart 3 تعبيرات switch التي تتيح لك استخدام switch كتعبير يُرجع قيمة. هذا أكثر إيجازاً ويزيل الحاجة لعبارات break.
صيغة تعبير Switch
void main() {
String day = 'Friday';
// تعبير switch -- يُرجع قيمة
String type = switch (day) {
'Monday' || 'Tuesday' || 'Wednesday' || 'Thursday' => 'يوم عمل',
'Friday' => 'تقريباً عطلة',
'Saturday' || 'Sunday' => 'عطلة نهاية الأسبوع',
_ => 'يوم غير صالح', // _ هو الافتراضي/البدل
};
print(type); // تقريباً عطلة
}
تعبير Switch مع الأعداد
void main() {
int statusCode = 200;
String message = switch (statusCode) {
200 => 'نجاح',
301 => 'تم إعادة التوجيه',
404 => 'غير موجود',
500 => 'خطأ في الخادم',
_ => 'غير معروف (\$statusCode)',
};
print(message); // نجاح
}
مطابقة الأنماط في Switch (Dart 3+)
جلب Dart 3 أيضاً مطابقة أنماط قوية لعبارات switch مما يتيح لك المطابقة على الأنواع والشروط وحتى تفكيك القيم.
أساسيات مطابقة الأنماط
void main() {
int age = 25;
String category = switch (age) {
< 0 => 'عمر غير صالح',
< 13 => 'طفل',
< 18 => 'مراهق',
< 60 => 'بالغ',
< 100 => 'كبير السن',
_ => 'عمر غير صالح',
};
print('العمر \$age: \$category'); // العمر 25: بالغ
}
عبارات if-case (Dart 3+)
يسمح Dart 3 أيضاً بمطابقة الأنماط مباشرة داخل عبارات if باستخدام if-case:
مطابقة أنماط if-case
void main() {
// فحص النوع وربط المتغير في خطوة واحدة
dynamic data = 'مرحبا Dart!';
if (data case String text) {
print('حصلنا على نص: \$text (الطول: ${text.length})');
}
// مع شرط حارس
int value = 42;
if (value case int n when n > 0 && n < 100) {
print('\$n بين 1 و 99');
}
// مطابقة أنماط القوائم
var list = [1, 2, 3];
if (list case [int first, int second, int third]) {
print('ثلاثة عناصر: \$first و \$second و \$third');
}
}
أمثلة عملية
مثال: مدقق تسجيل دخول بسيط
void main() {
String username = 'admin';
String password = 'secret123';
if (username.isEmpty || password.isEmpty) {
print('خطأ: الرجاء ملء جميع الحقول.');
} else if (username.length < 3) {
print('خطأ: اسم المستخدم يجب أن يكون 3 أحرف على الأقل.');
} else if (password.length < 8) {
print('خطأ: كلمة المرور يجب أن تكون 8 أحرف على الأقل.');
} else if (username == 'admin' && password == 'secret123') {
print('تم تسجيل الدخول بنجاح! مرحباً \$username.');
} else {
print('خطأ: اسم مستخدم أو كلمة مرور غير صحيحة.');
}
}
مثال: آلة حاسبة مع تعبير Switch
void main() {
double a = 10;
double b = 3;
String operator = '/';
String result = switch (operator) {
'+' => '\$a + \$b = ${a + b}',
'-' => '\$a - \$b = ${a - b}',
'*' => '\$a * \$b = ${a * b}',
'/' when b != 0 => '\$a / \$b = ${(a / b).toStringAsFixed(2)}',
'/' => 'خطأ: القسمة على صفر',
_ => 'خطأ: عامل غير معروف \$operator',
};
print(result); // 10.0 / 3.0 = 3.33
}
تمرين عملي
افتح DartPad وأنشئ برنامجاً: (1) استخدم سلسلة if-else if لتحديد تقدير الطالب الحرفي ورسالة التعليق بناءً على درجته (A: ممتاز، B: جيد، C: متوسط، D: أقل من المتوسط، F: راسب). (2) استخدم تعبير switch لتحويل رقم شهر (1-12) إلى اسمه. (3) استخدم شروطاً مركبة مع && و || للتحقق مما إذا كان الشخص مؤهلاً لخصم (إما طالب أو عمره فوق 60 وعضو). (4) استخدم عبارة if-case للتحقق مما إذا كانت قيمة ديناميكية عدداً صحيحاً موجباً.