سطور السجل

سطور السجل

تمرين تعلّمي

مقدمة

عند نمذجة بيانات لا يمكنها أن تأخذ إلا مجموعة محددة من الحالات الممكنة، مثل أيام الأسبوع أو اتجاهات البوصلة أو أزرار وحدة التحكم، فإن الأنواع الأساسية مثل Int أو String لها عيوب كبيرة. مع الأعداد الصحيحة أو السلاسل النصية، يجب أن يتحقق الكود باستمرار من القيم غير الصالحة (مثل رمز حالة 999 أو خطأ كتابي مثل "leftt")، ولا يستطيع القرّاء من البشر معرفة ما الذي تمثله الأرقام بسهولة.

يحل Swift هذه المشكلة باستخدام التعدادات (وكثيرًا ما تُختصر إلى enums). يُعرّف enum نوعًا مشتركًا لمجموعة من القيم المرتبطة المسماة. ولأن المترجم يعرف كل الحالات الممكنة مسبقًا، فإنه يستطيع التحقق من دقة كودك واكتماله في وقت الترجمة. ويمكن أن تحتوي التعدادات أيضًا على طرق ومهيّئات وخصائص محسوبة.

تعريف التعدادات

تُعرّف التعدادات باستخدام الكلمة المفتاحية enum متبوعةً باسم النوع، مع سرد حالاتها داخل الأقواس المعقوفة. بحسب اصطلاح Swift، يُكتب اسم النوع بـ UpperCamelCase، بينما تُكتب كل حالة بـ lowerCamelCase:

enum NESButton {
    case up
    case down
    case left
    case right
    case a
    case b
    case select
    case start
}

يمكنك أيضًا تعريف عدة حالات في سطر واحد تفصل بينها فواصل:

enum NESButton {
    case up, down, left, right, a, b, select, start
}

للإشارة إلى حالة تعداد، اكتب اسم نوع التعداد، ثم نقطة (.)، ثم اسم الحالة. وبمجرد أن يُعرف النوع أو يستطيع المترجم استنتاجه، يمكنك حذف اسم النوع واستخدام صيغة النقطة الأقصر:

var lastPressed = NESButton.up

// Swift infers the type, so you can omit the type name:
lastPressed = .down

let konamiCode: [NESButton] = [.up, .up, .down, .down, .left, .right, .left, .right, .b, .a]

الطرق والمهيّئات

يمكن للتعدادات أن تعرّف طرقًا ومهيّئات مخصصة تمامًا مثل الأصناف والبنى. وداخل طريقة في تعداد، يشير self إلى قيمة الحالة الحالية:

enum Coin {
    case heads
    case tails

    init(_ value: Int) {
        if value.isMultiple(of: 2) {
            self = .heads
        } else {
            self = .tails
        }
    }

    func flip() -> Coin {
        switch self {
        case .heads: return .tails
        case .tails: return .heads
        }
    }
}

let tails = Coin(13)     // .tails
let heads = Coin(0)      // .heads
let flipped = heads.flip() // .tails

القيم الخام

يمكن أن تُملأ حالات التعداد مسبقًا بقيم افتراضية تُسمى القيم الخام. يجب أن تشترك جميع القيم الخام في التعداد في النوع نفسه (مثل Int أو String أو Character):

enum NESButton: Character {
    case up = "⬆️"
    case down = "⬇️"
    case left = "⬅️"
    case right = "➡️"
    case a = "🅰️"
    case b = "🅱️"
    case select = "✅"
    case start = "🚦"
}

print(NESButton.left.rawValue) // Prints "⬅️"

يمكنك تهيئة تعداد من قيمة خام باستخدام init(rawValue:). ولأنه قد تُمرَّر قيمة خام غير صالحة، فإن هذا المهيّئ يُرجع قيمة اختيارية:

let upButton = NESButton(rawValue: "⬆️") // Optional(NESButton.up)
let invalid = NESButton(rawValue: "🙄")  // nil

يستطيع Swift إسناد القيم الخام تلقائيًا لتعدادات String و Int:

  • في تعدادات String، تكون القيمة الخام لكل حالة هي اسم الحالة افتراضيًا.
  • في تعدادات Int، تبدأ القيم الخام من 0 وتزداد بمقدار 1 ما لم يُحدَّد خلاف ذلك.
enum Planet: Int {
    case mercury = 1, venus, earth, mars
}

print(Planet.earth.rawValue) // Prints 3

التعليمات

في هذا التمرين ستتعامل مع أسطر السجل.

كل سطر سجل هو سلسلة نصية بالصيغة التالية: "[<LVL>]: <MESSAGE>".

هذه هي مستويات السجل المختلفة:

  • TRC (trace)
  • DBG (debug)
  • INF (info)
  • WRN (warning)
  • ERR (error)
  • FTL (fatal)

لديك ثلاث مهام، وعليك إكمال كل واحدة منها لتوفير الوظائف المطلوبة.

1. أنشئ تعداد LogLevel

عرّف تعداد LogLevel يحتوي على ست حالات تقابل مستويات السجل أعلاه، بالإضافة إلى حالة unknown للمستويات المفقودة أو غير القياسية.

  • trace
  • debug
  • info
  • warning
  • error
  • fatal
  • unknown

2. حلّل مستوى السجل

بعد ذلك، نفّذ مُهيّئ LogLevel لتحليل مستوى السجل في سطر السجل:

LogLevel("[INF]: File deleted")
// Returns LogLevel.info
LogLevel("Something went wrong!")
// Returns LogLevel.unknown

3. حوّل سطر السجل إلى صيغة مختصرة

مستوى السجل في سطر السجل مطوّل جدًا. لتقليل مساحة القرص اللازمة لتخزين أسطر السجل، طُوّرت صيغة مختصرة: "<ENCODED_LEVEL>:<MESSAGE>".

مستوى السجل المُرمّز هو ربط بسيط بين مستوى السجل وعدد:

  • trace - 0
  • debug - 1
  • info - 4
  • warning - 5
  • error - 6
  • fatal - 7
  • unknown - 42

نفّذ الطريقة shortFormat(message: String) -> String التي يمكنها إخراج صيغة سطر السجل المختصرة على هيئة String:

let overflow = LogLevel.error
overflow.shortFormat(message: "Stack overflow")
// Returns "6:Stack overflow"
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
Swift Exercism

مستعد لبدء سطور السجل؟

سجّل في Exercism لتتعلّم وتتقن Swift عبر 35 مفهومًا116 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.