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

do و try و catch

جزء من قسم المنطق والتدفق في رحلة Swift على Coddy — الدرس 45 من 56.

الصيغة الكاملة لمعالجة الأخطاء هي do/try/catch:

enum DivError: Error { case byZero }

func divide(_ a: Int, _ b: Int) throws -> Int {
    if b == 0 { throw DivError.byZero }
    return a / b
}

do {
    let r = try divide(10, 2)
    print(r)                      // 5
} catch DivError.byZero {
    print("can't divide by zero")
} catch {
    print("unknown error")
}

توضع try أمام أي استدعاء يرمي خطأ (throwing call). إذا قام الاستدعاء برمي خطأ، ينتقل التحكم إلى catch المطابقة؛ وبخلاف ذلك، يستمر التنفيذ متجاوزاً كتلة do.

تعمل عبارات catch المتعددة من الأعلى إلى الأسفل وتفوز أول مطابقة، تماماً مثل switch. عبارة catch المجردة في النهاية هي التي تلتقط كل شيء، وستحتاج إليها دائماً تقريباً لإبقاء المترجم (compiler) راضياً.

challenge icon

التحدي

سهل

قم بتعريف enum باسم ParseError: Error بثلاث حالات: empty، و notInteger، و negative.

قم بتعريف دالة قابلة لرمي الأخطاء (throwing function) باسم parsePositive(_ s: String) throws -> Int تقوم بما يلي:

  • ترمي .empty عندما يكون s فارغاً بعد إزالة المسافات البيضاء
  • ترمي .notInteger عندما لا يمكن تحليل s كـ Int
  • ترمي .negative عندما تكون القيمة المحللة < 0
  • خلاف ذلك، تعيد القيمة المحللة

اقرأ سطراً واحداً من stdin واستدعِ parsePositive داخل كتلة do/catch. اطبع:

  • got: <n> عند النجاح
  • error: empty، أو error: not integer، أو error: negative لكل حالة خطأ

بالنسبة للمدخل 42، يكون المخرج got: 42. وللسطر الفارغ، يكون error: empty. وللمدخل abc يكون error: not integer.

ورقة مرجعية

يستخدم نظام معالجة الأخطاء في Swift الكلمات do/try/catch. قم بتعريف الأخطاء باستخدام enum يتوافق مع Error، وقم بتمييز الدوال التي تطرح أخطاء بكلمة throws، واستخدم throw لإثارة خطأ:

enum DivError: Error { case byZero }

func divide(_ a: Int, _ b: Int) throws -> Int {
    if b == 0 { throw DivError.byZero }
    return a / b
}

do {
    let r = try divide(10, 2)
    print(r)                      // 5
} catch DivError.byZero {
    print("can't divide by zero")
} catch {
    print("unknown error")        // التقاط كافة الأخطاء
}
  • يجب أن تسبق try كل استدعاء يطرح خطأ.
  • يتم مطابقة عبارات catch من الأعلى إلى الأسفل؛ أول مطابقة هي التي تُنفذ.
  • تعمل عبارة catch المجردة في النهاية كملتقط شامل لكافة الأخطاء.

جرّب بنفسك

let line = readLine()!

// مهام: enum ParseError; func parsePositive(_:) throws -> Int;
// do/try/catch مع ثلاثة فروع بالإضافة إلى الفرع الشامل (catch-all)
quiz iconاختبر نفسك

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

جميع دروس المنطق والتدفق