تخطَّ إلى المحتوى

الشروط في Swift: if و switch و guard

الدرس 3 من 11 · Swift

تطبيقات iPhone تتخذ قرارات في كل لحظة: هل كلمة المرور صحيحة؟ هل البطارية منخفضة؟ هل الوضع الليلي مفعّل؟ في هذا الدرس ستتعلم أدوات القرار في Swift، ومعها أداتان تتميز بهما: switch القوي الذي يحميك من نسيان الحالات، و guard التي تجعل الكود أنظف.

let score = 72
if score >= 90 {
print("ممتاز")
} else if score >= 50 {
print("ناجح")
} else {
print("راسب")
}
الناتج
ناجح

لاحظ: في Swift لا تحتاج أقواساً حول الشرط، لكن الأقواس المعقوفة { } إجبارية حتى لو كان الجسم سطراً واحداً. هذا القرار في تصميم اللغة يمنع أخطاء شهيرة في لغات أخرى.

والشرط يجب أن يكون Bool حرفياً: if score خطأ ترجمة في Swift، على عكس C.

العوامل المنطقية: && (و)، و || (أو)، و ! (ليس):

let age = 16
let hasTicket = true
if age >= 13 && hasTicket {
print("تفضل بالدخول")
}
الناتج
تفضل بالدخول
let stock = 0
let status = stock > 0 ? "متوفر" : "غير متوفر"
print(status)
الناتج
غير متوفر
let day = "الجمعة"
switch day {
case "الجمعة", "السبت":
print("عطلة نهاية الأسبوع")
case "الأحد":
print("أول أيام الدراسة")
default:
print("يوم دراسي عادي")
}
الناتج
عطلة نهاية الأسبوع

ثلاثة أشياء تميز switch في Swift:

  1. لا انزلاق: بعد تنفيذ الحالة المطابقة، يخرج switch تلقائياً، فلا تحتاج break كما في C و Java.
  2. إجبارية الشمول: يجب أن تغطي كل الاحتمالات. مع النصوص والأرقام يعني ذلك وجود default. إذا نسيتها، يرفض المترجم الكود: switch must be exhaustive.
  3. عدة قيم في حالة واحدة بفاصلة: case "الجمعة", "السبت":.

مع المجالات:

let grade = 85
switch grade {
case 90...100:
print("A")
case 75..<90:
print("B")
default:
print("C")
}
الناتج
B
  • 90...100: من 90 إلى 100 شاملة.
  • 75..<90: من 75 إلى 89، أي بدون 90.

تخيّل switch مثل آلة بيع المشروبات: كل زر يعطيك مشروباً واحداً فقط (لا انزلاق)، والآلة مصممة بحيث يكون لكل زر نتيجة، فلا يوجد زر يضيع نقودك (الشمول).

guard شرط يقول: «تأكد من هذا، وإلا اخرج فوراً»:

func checkAge(_ text: String) {
guard let age = Int(text) else {
print("اكتب رقماً صحيحاً")
return
}
guard age >= 13 else {
print("التطبيق لمن عمرهم 13 فأكثر")
return
}
print("أهلاً بك، عمرك \(age)")
}
checkAge("abc")
checkAge("10")
checkAge("15")
الناتج
اكتب رقماً صحيحاً
التطبيق لمن عمرهم 13 فأكثر
أهلاً بك، عمرك 15
  • جسم else في guard يجب أن يخرج من الدالة، بـ return غالباً.
  • الميزة الكبرى: guard let age = ... تفتح الاختياري، ويبقى age متاحاً في باقي الدالة بعدها، وليس داخل قوسين فقط كما في if let.

تخيّل guard مثل حارس عند مدخل المبنى: يفحص الشروط واحداً واحداً عند الباب، ومن لا يستوفيها يُرد فوراً. ومن يدخل، يتحرك بحرية في المبنى كله. هذا يجعل الكود مستقيماً ومقروءاً، بدلاً من شروط if متداخلة داخل بعضها.

(ستتعلم الدوال بالتفصيل في الدرس الخامس، والمهم هنا فكرة guard.)

  1. اكتب switch على متغير month (رقم من 1 إلى 12) يطبع الفصل: الشتاء والربيع والصيف والخريف، مستخدماً عدة قيم في كل حالة.
  2. اكتب switch على درجة الحرارة بالمجالات: أقل من 15 «بارد»، ومن 15 إلى 28 «معتدل»، وأكثر «حار».
  3. اكتب دالة login(username: String, password: String) تستخدم guard لترفض اسم المستخدم الفارغ (تلميح: username.isEmpty)، وكلمة المرور الأقصر من 6 حروف، ثم تطبع «تم الدخول».
  • نسيان default في switch: خطأ switch must be exhaustive.
  • محاولة كتابة if بلا أقواس معقوفة: خطأ ترجمة، حتى لسطر واحد.
  • guard بدون خروج: جسم else في guard يجب أن ينتهي بـ return أو ما يخرج من النطاق.

سؤال

ماذا يحدث في switch بلغة Swift بعد تنفيذ الحالة المطابقة؟

سؤال

ما الميزة الأساسية لـ guard let مقارنة بـ if let؟

  • if بلا أقواس حول الشرط، لكن الأقواس المعقوفة إجبارية، والشرط Bool فقط.
  • المعامل الثلاثي لاختيار قيمة في سطر واحد.
  • switch بلا انزلاق، ويجب أن يغطي كل الاحتمالات، ويقبل عدة قيم ومجالات.
  • ... مجال شامل، و ..< مجال بدون الطرف الأخير.
  • guard للخروج المبكر، وتبقى قيمها المفتوحة متاحة في باقي الدالة.