المكررات المخصصة
جزء من قسم البرمجة كائنية التوجّه في رحلة GDScript على Coddy. الدرس 33 من 65.
تجعل Python الصنف يتصرف كقائمة باستخدام أساليب سحرية مثل __len__ و__getitem__ و__contains__ و__iter__. تحتوي Godot على أساليب افتراضية لمهمة واحدة فقط من هذه المهام، وهي حلقة for. تجعل ثلاث أساليب العبارة for item in my_object: تعمل:
- تُنفَّذ
_iter_init(iter)مرة واحدة، قبل الجولة الأولى. وتضبط موضع البداية وتُرجعtrueإذا كان هناك عنصر أول. - تُرجع
_iter_get(position)العنصر عند الموضع الحالي، ويحصل متغير الحلقة على تلك القيمة. - تُنفَّذ
_iter_next(iter)قبل كل جولة تالية. وتنقل الموضع إلى العنصر التالي وتُرجعfalseعندما لا تبقى عناصر، ما ينهي الحلقة.
# team.gd
class_name Team
extends RefCounted
var _members: Array[String] = []
func add(member: String) -> void:
_members.append(member)
func _iter_init(iter: Array) -> bool:
iter[0] = 0
return iter[0] < _members.size()
func _iter_next(iter: Array) -> bool:
iter[0] += 1
return iter[0] < _members.size()
func _iter_get(position):
return _members[position]iter هي مصفوفة تحتوي على خانة واحدة، وينشئها Godot لكل حلقة. تحتوي iter[0] على موضع تلك الحلقة، ويمرر Godot قيمتها إلى _iter_get(). تعمل Team الآن ضمن حلقة for:
var team := Team.new()
team.add("Ada")
team.add("Bo")
for member in team:
print(member) # Ada، ثم Boاحتفظ بالموضع في iter[0]، وليس في متغير عضو مثل _position. لكل حلقة iter خاص بها، لذا فإن حلقتين على الفريق نفسه، حتى لو كانت إحداهما داخل الأخرى، لا تؤثر إحداهما في الأخرى. أما مع متغير عضو، فستغيّر الحلقة الداخلية موضع الحلقة الخارجية.
لا توجد طريقة افتراضية للعمليات الأخرى على القائمة: إن len(team) وteam[0] تعبيران خاطئان. اكتب طرقًا عادية بأسماء مثل تلك المستخدمة في Array، مثل size() وget_at(index) وhas(member). لا تختبر وجود عنصر باستخدام in: فالتعبير "Ada" in team يتحقق مما إذا كان لدى Team خاصية أو طريقة باسم Ada، لذا تكون نتيجته false.
التحدي
سهلاكتب الصنف Bookshelf في الملف bookshelf.gd. يحتفظ بالعناوين في _titles ولا يستوعب أكثر من _capacity كتب:
- تضيف
add(title)العنوان وتُرجعtrue، أو تُرجعfalseدون إضافة إذا كان الرف ممتلئًا أو كان العنوان موجودًا فيه بالفعل. - تُرجع
size()عدد الكتب، وتُرجعhas(title)ما إذا كان العنوان موجودًا على الرف. - تُرجع
get_at(index)العنوان عند ذلك الفهرس، أو سلسلة فارغة إذا كان الفهرس خارج نطاق الرف. - تتيح
_iter_init()و_iter_next()و_iter_get()لحلقةforالمرور على العناوين بالترتيب الذي أُضيفت به.
يقرأ الكود المقدَّم السعة وعدد العناوين وعنوانًا واحدًا في كل سطر، ويعرض العناوين التي تعذرت إضافتها. ثم يطبع عدد الكتب، ويسردها باستخدام حلقة for تمر على الرف، ثم يقرأ عنوانًا آخر ويطبع ما إذا كان الرف يحتوي عليه، ويطبع الكتاب الأخير. عند السعة 3، والعناوين Dune وEmma وDune وUlysses وHamlet، والبحث عن Emma، يطبع:
Could not add: Dune
Could not add: Hamlet
Books: 3
1. Dune
2. Emma
3. Ulysses
Has Emma: true
Last: Ulyssesضع التعليمات البرمجية في bookshelf.gd. يحتوي main.gd على كود الإدخال والإخراج المقدَّم، ولا يمكن تعديله.
جرّب بنفسك
extends Node
func _ready():
# كود الإدخال/الإخراج المرفق: أبقه كما هو
var shelf := Bookshelf.new(int(OS.read_string_from_stdin()))
var count := int(OS.read_string_from_stdin())
for i in count:
var title := OS.read_string_from_stdin()
if not shelf.add(title):
print("Could not add: " + title)
print("Books: %d" % shelf.size())
var number := 1
for title in shelf:
print("%d. %s" % [number, title])
number += 1
var query := OS.read_string_from_stdin()
print("Has %s: %s" % [query, shelf.has(query)])
print("Last: " + shelf.get_at(shelf.size() - 1))
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجّه
1أساسيات البرمجة كائنية التوجه
الملفات الخارجيةمقدمة إلى البرمجة كائنية التوجهالفئات مقابل الكائناتالكلمة المفتاحية selfالأساليبالخصائصالمُنشئ (_init)مراجعة - آلة حاسبة بسيطة4تعدد الأشكال
إعادة النظر في تجاوز الأساليبكتابة الأنواع بأسلوب البطةالفئات والأساليب المجرّدةتصميم الواجهاتمراجعة - حاسبة الأشكال10أنماط التصميم، الجزء الثاني
نمط الأوامرنمط المحوّلنمط المُزيّننمط الطريقة القالبيةنمط الحالةالنمط المركّب2خصائص الأصناف
متغيرات الكائن مقابل المتغيرات الساكنةالدوال الساكنةمُعيِّنات الخصائصمُسترجِعات الخصائصخاص وفقًا للاتفاقيةمراجعة - مدير الحسابات البنكية5التغليف
الأعضاء العامة والخاصةالتحقق من الصحة باستخدام دوال الضبطإخفاء المعلوماتالخصائص للقراءة فقطمراجعة - نظام سجلات الطلاب8مفاهيم متقدمة في البرمجة كائنية التوجه
التركيب مقابل الوراثةالأصناف الداخليةالعُقد كمكوّناتRefCounted مقابل Nodeالتعدادات في الأصنافتدرّب بنفسك: مترجم GDScript عبر الإنترنت