English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

المحولات في Lua

المكرر (iterator) هو كائن يمكن استخدامه للمرور عبر جزء أو جميع العناصر في كائن من مكتبة القوالب النموذجية، وكل كائن مكرر يمثل عنوانًا محددًا في الكائن.

في لغة Lua، المكرر هو بنية داعمة لنوع الاشارة، والتي يمكنها مرور كل عنصر في الجمعية.

مكتبة for الجاهزة

مكتبة for الجاهزة تحتفظ بالوظيفة التكرارية في داخله، حيث يحتفظ بالثلاثة قيم التالية: وظيفة التكرار، المعلمة الثابتة، المعلمة التحكمية.

مكتبة for الجاهزة توفر زوجات المفاتيح/القيم للجمعيات، وتحمل نموذج الجملة التالي:

for k, v in pairs(t) do
    print(k, value)
end

في الكود أعلاه، k, v هي قائمة متغيرات؛pairs(t) هي قائمة تعبيرات.

انظر الأمثلة التالية:

array = {"Google", "w3codebox"}
for key, value in ipairs(array) 
do
   print(key, value)
end

نتيجة تنفيذ الكود هي:

1		Google
2		w3codebox

في هذا المثال،استخدمنا وظيفة التكرار المقدمة بشكل افتراضي بواسطة Lua ipairs.

دعونا نرى كيف يتم تنفيذ for عامة أدناه:

  • أولاً،البدء،حساب قيمة التعبير بعد in،ويجب أن يكون التعبير قيمة يجب أن تعود الثلاثة قيم التي تتطلبها for عامة:وظيفة التكرار والحالة الثابتة والمتغير التحكمي؛تمامًا مثل التوزيع المزدوج،إذا كانت عدد القيم التي يعود إليها التعبير أقل من ثلاثة،فسيتم تعيين القيم المفقودة إليها nil،وسيتم تجاهل القيم الزائدة.

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

  • ثالثًا،تعيين قيمة وظيفة التكرار العائدة إلى قائمة المتغيرات.

  • رابعًا،إذا كان القيمة الأولى التي يعود إليها هي nil،ينتهي الدوران،إلا إذا كانت القيمة الأولى ليست nil،فسيتم تنفيذ الجسم الداخلي للدوران.

  • خامسًا،تكرار الدورة الثانية مرة أخرى لتعيين وظيفة التكرار

في Lua،نستخدم دائمًا الوظائف لوصف المكرر،ويرجع كل تكرار قيمة العنصر التالي في المجموعة.ويشمل المكرر في Lua نوعين من النوعين التاليين:

  • المكرر غير المكتسب

  • عندما يبدأ Lua في التدوير باستخدام ipairs(a)، يحصل على ثلاثة قيم: دالة التدوير iter، معرف الحالة الثابت a، والقيمة الابتدائية للسيطرة على المتغير 0؛ ثم يُطلق Lua iter(a,0) ليعود 1, a[1] (ما لم يكن a[1]=nil);ثم يتم استدعاء التدوير المقبل iter(a,1) ليعود 2, a[2]…… حتى العنصر الأول الذي هو nil.

المكرر غير المكتسب

المكرر غير المكتسب هو مكرر لا يحتفظ بأي حالة،لذلك يمكننا استخدام المكرر غير المكتسب في الدورات لتجنب تكلفة إنتاج الكابلات الإضافية.

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

مثال نموذجي بسيط لل迭代ر غير المكتسب هو ipairs،ويجري تمرير كل عنصر في المجموعة.

في هذا المثال،استخدمنا وظيفة بسيطة لتطبيق المكرر،لتحقيق مربع الرقم n:

function square(iteratorMaxCount, currentNumber)
   if currentNumber<iteratorMaxCount
   then
      currentNumber = currentNumber+1
   return currentNumber, currentNumber*currentNumber
   end
end
for i, n in square, 3, 0
do
   print(i, n)
end

نتائج الإخراج في الأمثلة أعلاه هي:

1		1
2		4
3		9

الوضع المتكرر يشمل الجدول المبحوث (الحالة الثابتة التي لا تتغير خلال العملية المتكررة) ومؤشر الإندماج الحالي (المتغير التحكمي)،وipairs ووظيفة التكرار بسيطتان،ويمكننا تنفيذ ذلك في Lua كما يلي:

function iter (a, i)
    i = i + 1
    local v = a[i]
    if v then
       return i, v
    end
end
 
function ipairs (a)
    return iter, a, 0
end

return iter, a, 0

عندما يبدأ Lua في التدوير باستخدام ipairs(a)، يحصل على ثلاثة قيم: دالة التدوير iter، معرف الحالة الثابت a، والقيمة الابتدائية للسيطرة على المتغير 0؛ ثم يُطلق Lua iter(a,0) ليعود 1, a[1] (ما لم يكن a[1]=nil);ثم يتم استدعاء التدوير المقبل iter(a,1) ليعود 2, a[2]…… حتى العنصر الأول الذي هو nil.

محولات الحالة المتعددة

في بعض الحالات، يحتاج المحول إلى حفظ بيانات حالة متعددة وليس بيانات حالة ثابتة بسيطة وسيطرة على المتغيرات، أسهل طريقة هي استخدام الدالة المغلقة، هناك طريقة أخرى هي وضع جميع بيانات الحالة في جدول، واستخدام الجدول كمعرف حالة المحول، لأن في هذه الحالة يمكن حفظ جميع المعلومات في الجدول، لذا لا تحتاج دالة التحويل إلى معامل ثاني.

array = {"Google", "w3codebox"}
function elementIterator (collection)
   local index = 0
   local count = #collection
   -- دالة مغلقة
   return function ()
      index = index + 1
      إذا كان index <= count
      then
         -- العنصر الحالي للمحول
         return collection[index]
      end
   end
end
لـ element in elementIterator(array)
do
   print(element)
end

نتائج الإخراج في الأمثلة أعلاه هي:

Google
w3codebox

في الأمثلة أعلاه، يمكننا رؤية أن elementIterator قد استخدمت الدالة المغلقة لتحقق من حجم المجموعة وإخراج العناصر.