0Pricing
Swift Academy · درس

المطابقة الشرطية

اجعل النوع العام يطابق البروتوكول فقط عند استيفاء القيود.

المطابقة الشرطية درس مجاني في Swift Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Swift Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Swift Academy 4 دروس في المجموع.

ما التوافق المشروط؟

يجعل التوافق المشروط النوع العام متوافقًا مع بروتوكول ما فقط عندما تستوفي معلمات نوعه قيودًا معينة. والمثال الكلاسيكي هو أن Array تكون Equatable فقط إذا كان Element الخاص بها من النوع Equatable.

extension Array where Element: Equatable {
    func allEqual(to x: Element) -> Bool {
        allSatisfy { $0 == x }
    }
}

مثال مضمّن

تستخدم المكتبة القياسية هذا بالفعل: تكون [Int] من النوع Equatable لأن Int كذلك. وتقارن مصفوفتان متساويتان عنصرًا بعنصر.

let a = [1, 2, 3]
let b = [1, 2, 3]
print(a == b)

تعريف التوافق المشروط

اكتبوا امتدادًا يضيف التوافق مع بروتوكول باستخدام جملة where. هنا، يتوافق غلاف مع Equatable فقط عندما يتوافق نوع قيمته معها.

struct Pair<T> {
    let first: T
    let second: T
}

extension Pair: Equatable where T: Equatable {
    static func == (l: Pair, r: Pair) -> Bool {
        l.first == r.first && l.second == r.second
    }
}

print(Pair(first: 1, second: 2) == Pair(first: 1, second: 2))

سبب أهمية القيد

من دون القيد، لن يتمكن المصرّف من توليد == تلقائيًا، لأن مقارنة القيمة المغلّفة تتطلب أن تكون القيمة نفسها قابلة للمقارنة. وتوفّر جملة where هذا الضمان تحديدًا.

struct Box<T> { let value: T }
extension Box: Equatable where T: Equatable {}

print(Box(value: "hi") == Box(value: "hi"))
print(Box(value: 5) == Box(value: 9))

التوافق المشروط مع Codable

يمكنكم جعل النوع متوافقًا مع Codable بشكل مشروط. وتكون الحاوية قابلة للترميز فقط عندما يكون عنصرها كذلك.

struct Wrapper<T> { let payload: T }
extension Wrapper: Codable where T: Codable {}

let w = Wrapper(payload: 42)
let data = try! JSONEncoder().encode(w)
print(String(data: data, encoding: .utf8)!)

قيود متعددة

يمكن أن تسرد جملة where عدة متطلبات مفصولة بفواصل.

struct Stack<T> { var items: [T] = [] }

extension Stack where T: Comparable {
    func maxItem() -> T? { items.max() }
}

var s = Stack<Int>()
s.items = [3, 9, 1]
print(s.maxItem()!)

التوافق المشروط مع CustomStringConvertible

اجعلوا النوع قابلًا للطباعة فقط عندما تكون محتوياته كذلك، مع تركيب الأوصاف من العناصر.

struct Labeled<T> { let label: String; let value: T }

extension Labeled: CustomStringConvertible where T: CustomStringConvertible {
    var description: String { label + ": " + value.description }
}

print(Labeled(label: "Age", value: 30))

التوافق المشروط المتداخل

يُركّب التوافق المشروط بعضه فوق بعض: فمصفوفة من مصفوفات Int تكون من النوع Equatable لأن كل طبقة تتابع تطبيق القيد.

let grid1 = [[1, 2], [3, 4]]
let grid2 = [[1, 2], [3, 4]]
print(grid1 == grid2)

التقييد ببروتوكول آخر

يمكن لجملة where أن تطلب توافق العنصر مع بروتوكول عرّفتموه، مما يتيح سلوكًا مبنيًا على ذلك البروتوكول.

protocol Priced { var price: Double { get } }
struct Item: Priced { let price: Double }

extension Array where Element: Priced {
    var totalPrice: Double { reduce(0) { $0 + $1.price } }
}

print([Item(price: 1.5), Item(price: 2.5)].totalPrice)

قيود تساوي النوع

يمكنكم تقييد نوع مرتبط ليكون من نوع محدد باستخدام ==. وهنا لا تنطبق الأساليب إلا على مصفوفات من النوع String.

extension Array where Element == String {
    func joinedUpper() -> String {
        map { $0.uppercased() }.joined(separator: "-")
    }
}

print(["a", "b", "c"].joinedUpper())

كيفية استخدام المصرّف له

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

struct Optional2<T> { let value: T? }
extension Optional2: Equatable where T: Equatable {
    static func == (l: Optional2, r: Optional2) -> Bool { l.value == r.value }
}
print(Optional2(value: 1) == Optional2(value: 1))

اختبار سريع

اختبروا مدى فهمكم للتوافق المشروط.

مراجعة

يستخدم التوافق المشروط الصيغة extension Type: Protocol where ... لمنح التوافق فقط عندما تستوفي معلمات النوع القيود. وقد رأيتم استخدامه مع Equatable وCodable وCustomStringConvertible، ومع قيود البروتوكولات وقيود تساوي النوع (==) والتداخل. وهو يحافظ على أمان الأنواع العامة وقابليتها لإعادة الاستخدام.

الأسئلة الشائعة

هل درس «المطابقة الشرطية» مجاني؟

نعم — نص درس «المطابقة الشرطية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Swift Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Swift Academy 4 دروس في المجموع.

ماذا ستتعلم في «المطابقة الشرطية»؟

اجعل النوع العام يطابق البروتوكول فقط عند استيفاء القيود. تتمرن على Swift Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Swift Academy؟

لا تُشترط خبرة سابقة. Swift Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «المطابقة الشرطية»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Swift Academy هذا؟

نعم. كل درس في Swift Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. البروتوكولات كعقود
  2. التنفيذات الافتراضية في الامتدادات
  3. تركيب البروتوكولات
  4. المطابقة الشرطية
← العودة إلى Swift Academy