الـ Metamethods الحسابية - الجزء الأول
جزء من قسم Logic & Flow في رحلة Lua على Coddy — الدرس 21 من 54.
لقد تعلمت كيفية تخصيص ما يحدث عند طباعة جدول باستخدام __tostring. الآن ستكتشف أن الجداول الوصفية (metatables) يمكنها أيضاً تحديد ما يحدث عند استخدام العمليات الحسابية مثل + و - على جداولك.
عادةً، إذا حاولت جمع جدولين معاً باستخدام عامل التشغيل +، ستعطيك لغة Lua خطأً لأنها لا تعرف كيفية جمع الجداول. ولكن باستخدام الطرق الوصفية الحسابية (arithmetic metamethods)، يمكنك تحديد معنى الجمع بالضبط لأنواع البيانات المخصصة الخاصة بك.
تتحكم الطريقة الوصفية (metamethod) __add في سلوك عملية الجمع. عندما تواجه Lua عامل التشغيل + بين قيمتين ويكون لدى إحداهما على الأقل جدول وصفي (metatable) يحتوي على __add، فإنها تستدعي تلك الدالة بدلاً من إظهار خطأ:
local v1 = {x = 3, y = 4}
local v2 = {x = 1, y = 2}
local meta = {
__add = function(a, b)
return {x = a.x + b.x, y = a.y + b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 + v2
print(v3.x, v3.y) -- النتيجة: 4 6تستقبل الدالة __add وسيطين: المعامل الأيسر والمعامل الأيمن. في هذا المثال، تقوم بإنشاء جدول جديد بقيم x و y التي تمثل مجموع القيم المقابلة من كلا جدولي الإدخال.
وبالمثل، فإن الطريقة الوصفية __sub تتحكم في عملية الطرح باستخدام المعامل -:
local meta = {
__sub = function(a, b)
return {x = a.x - b.x, y = a.y - b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 - v2
print(v3.x, v3.y) -- النتيجة: 2 2تُسمى هذه القدرة على تعريف سلوك مخصص للمعاملات بـ operator overloading.
التحدي
سهلاكتب دالة addVectors تأخذ x1، و y1، و x2، و y2 وتعيد نتيجة جمع متجهين معاً.
قم بإنشاء جدولين للمتجهات بالإحداثيات المعطاة، وأرفق جدولاً وصفياً (metatable) يحتوي على ميثود __add لتمكين جمع المتجهات، ثم اجمعهما باستخدام عامل التشغيل +، وأعد النتيجة كسلسلة نصية منسقة.
المنطق:
- أنشئ جدول المتجه الأول بالمفاتيح
x = x1وy = y1 - أنشئ جدول المتجه الثاني بالمفاتيح
x = x2وy = y2 - أنشئ جدولاً وصفياً (metatable) باستخدام
__addيأخذ متجهين ويعيد جدولاً جديداً بـx = a.x + b.xوy = a.y + b.y - أرفق الجدول الوصفي بكلا جدولي المتجهات باستخدام
setmetatable() - اجمع المتجهين باستخدام
v1 + v2 - أعد النتيجة كسلسلة نصية بالتنسيق
"x y"(قيم x و y مفصولة بمسافة)
المعاملات:
x1(number): إحداثي x للمتجه الأولy1(number): إحداثي y للمتجه الأولx2(number): إحداثي x للمتجه الثانيy2(number): إحداثي y للمتجه الثاني
المخرجات: مجموع المتجهين كسلسلة نصية بالتنسيق "x y" (string)
ورقة مرجعية
يمكن للجداول الوصفية (Metatables) تحديد ما يحدث عند استخدام العمليات الحسابية مثل + و - على الجداول. يسمى هذا بتحميل العوامل بشكل زائد (operator overloading).
تتحكم الطريقة الوصفية (metamethod) المسماة __add في سلوك الجمع باستخدام العامل +:
local v1 = {x = 3, y = 4}
local v2 = {x = 1, y = 2}
local meta = {
__add = function(a, b)
return {x = a.x + b.x, y = a.y + b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 + v2
print(v3.x, v3.y) -- النتيجة: 4 6تستقبل الدالة __add وسيطين: المعامل الأيسر والمعامل الأيمن.
تتحكم الطريقة الوصفية __sub في عملية الطرح باستخدام العامل -:
local meta = {
__sub = function(a, b)
return {x = a.x - b.x, y = a.y - b.y}
end
}
setmetatable(v1, meta)
setmetatable(v2, meta)
local v3 = v1 - v2
print(v3.x, v3.y) -- النتيجة: 2 2جرّب بنفسك
function addVectors(x1, y1, x2, y2)
-- اكتب الكود هنا
end
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Logic & Flow
1التكرار المتقدم عبر الجداول
التكرار باستخدام pairs()التكرار باستخدام ipairs()pairs() مقابل ipairs()مراجعة - ورقة الشخصية4مقدمة إلى Metatables
ما هو الـ Metatable؟setmetatable و getmetatableالـ Metamethod المسماة __indexالـ Metamethod المسماة __newindexالـ Metamethod المسماة __tostringالـ Metamethods الحسابية - الجزء الأولالـ Metamethods الحسابية - الجزء الثانيملخص - جدول للقراءة فقط2المزيد من دوال مكتبة Table
table.concat()إنشاء الجداول و unpack()table.sort()فرز مخصص باستخدام الدوالمراجعة - لوحة أعلى النتائج