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

إرجاع Closures

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

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

func multiplier(_ k: Int) -> (Int) -> Int {
    return { n in n * k }
}

let triple = multiplier(3)
let tenfold = multiplier(10)
print(triple(4))                  // 12
print(tenfold(4))                 // 40

يلتقط الإغلاق (closure) المُرجع k، لذا فإن كل استدعاء لـ multiplier(...) ينتج إغلاقاً جديداً تماماً بـ k الخاصة به.

هذا النمط هو جوهر كود "الاستراتيجية" (strategy) في Swift: اكتب دالة تأخذ إعدادات (configuration) وتُرجع إغلاقاً (closure)، ثم مرر هذا الإغلاق إلى map أو filter أو sorted(by:) أو أي مكان آخر يُتوقع فيه قيمة على شكل دالة.

challenge icon

التحدي

متوسط

قم ببناء مصنعين للإغلاقات (closure factories):

  • greaterThan(_ k: Int) -> (Int) -> Bool: تعيد دالة منطقية (predicate) تكون true عندما يكون المعامل الخاص بها أكبر تماماً من k
  • scaleBy(_ k: Int) -> (Int) -> Int: تعيد دالة تضرب المعامل الخاص بها في k

اقرأ ثلاثة أسطر:

  1. عدد صحيح threshold
  2. عدد صحيح scale
  3. قائمة من الأعداد الصحيحة مفصولة بفاصلة، وهي nums

اطبع ثلاثة أسطر:

  1. الأرقام التي تتجاوز العتبة (قم بالتصفية باستخدام الإغلاق من greaterThan)، مدمجة بـ ,
  2. نفس الأرقام، بعد تغيير حجمها (استخدم الخريطة map مع scaleBy)، مدمجة بـ ,
  3. عدد الأرقام التي اجتازت التصفية

للمدخلات 5 / 3 / 2,7,3,8,9، تكون المخرجات:

7,8,9
21,24,27
3

ورقة مرجعية

إنّ مصنع الإغلاقات (closure factory) هو دالة تلتقط معاملاً وتُرجع إغلاقاً جديداً مهيأً بواسطته:

func multiplier(_ k: Int) -> (Int) -> Int {
    return { n in n * k }
}

let triple = multiplier(3)
print(triple(4))   // 12

تنتج كل عملية استدعاء إغلاقاً جديداً تماماً بقيمته الملتقطة الخاصة لـ k. يمكن تمرير الإغلاقات المرجعة مباشرة إلى map، و filter، و sorted(by:)، وما إلى ذلك:

func greaterThan(_ k: Int) -> (Int) -> Bool {
    return { n in n > k }
}

let nums = [2, 7, 3, 8, 9]
let filtered = nums.filter(greaterThan(5))  // [7, 8, 9]
let scaled = filtered.map(multiplier(3))    // [21, 24, 27]

جرّب بنفسك

let threshold = Int(readLine()!)!
let scale = Int(readLine()!)!
let nums = readLine()!.components(separatedBy: ",").map { Int($0)! }

// TODO: greaterThan، scaleBy؛ التصفية (filter) ثم التعيين (map)؛ طباعة العناصر مدمجة والعدد
quiz iconاختبر نفسك

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

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