تعلّم البرمجة بلغة كوتلن (39): تفكيك التصريحات Destructuring Declarations

تعلّم البرمجة بلغة كوتلن (39): تفكيك التصريحات Destructuring Declarations
أستمع الى المقال

تحدثنا في دروس سابقة، عن كيفية التصريح أو الإعلان عن المتغيرات Variables عبر استخدام الكلمتين المفتاحيتين var و val. في هذا الدرس، سنشرح إحدى المفاهيم في كوتلن، والتي تمكننا من تفكيك الخاصيات التي صرحنا أو أعلنا عنها في كائن معين إلى عدة متغيرات. وهو المفهوم الذي يعرف باسم Destructuring Declarations.

تفكيك التصريحات مع صنف بيانات Data Class:

في بعض الأحيان يكون من الملائم تفكيك كائن ما، إلى عدد من المتغيرات. ويكون شكل هذا التفكيك في أبسط صوره:

val (variable1, variable2, variable3, …) = Object

نضع عدد من المتغيرات بين قوسين ( )، مساوي لعدد الخاصيّات في كائنٍ ما، أو عدد متغيرات أقل من الخاصيّات، ولكن العكس ليس صحيح. ويجب أن تكون المتغيرات، بنفس ترتيب الخاصيّات في الصنف الذي يتم إنشاء الكائن منه.

فمثلًا، إذا كان لدينا صنف بيانات يُمثل مستخدم User، ويحتوي على ثلاث خاصيّات:

data class User(val username: String, val email: String, val password: String)

حين إنشاء كائن من هذا الصنف في دالة ()main، يمكننا إسناد كل خاصيّة لمتغير في سطر جديد، باستخدام الكائن:

وعند تنفيذ الشفرة سيتم طباعة: Welcome Admin.

أو يمكننا استخدام طريقة التفكيك:

سيتم تفكيك الكائن User، إلى عدد ثلاث متغيرات: username, email, password. الطريقتان متساويتان وتؤديان إلى نفس النتيجة. فقط أن طريقة التفكيك بها شفرة أقل بمقدار ثلاث أسطر. وهذا الأمر مفيد بشكل خاص في البرامج الكبيرة.

ولكن كيف حدث ذلك؟ كيف استطعنا تفكيك الكائن User؟ 

هذا حدث لأن صنف الـ User أعلاه، هو صنف بيانات لأننا بدأناه بالكلمة المفتاحية data. هذه الكلمة، بالإضافة للدوال الأربع التي تولّدها تلقائيًا داخل الصنف، كما شرحنا في الدرس السابق، تُنشئ له دالة إضافية تسمى ()componentN.

دالة ()componentN:

يتم إنشاء هذه الدالة تلقائيًا عند استخدام الكلمة المفتاحية data مع أي صنف نُنشئه. ويُمثل الحرف N، عدد الخاصيّات في الصنف. ويتم إنشاء دالة باسم ()component1 للخاصيّة الأولى في الصنف، ودالة ()component2 للثانية، ودالة ()component3 للثالثة … وهكذا حسب عدد الخاصيّات في الصنف، يتغير الرقم في الدالة.

لذلك، إذا عدنا لصنف User وفعلنا التالي:

في هذه الحالة أيضًا، سيتم اسناد خاصيّات الـ User، إلى المتغيرات الثلاث. وعند إضافة خاصيّة جديدة بعد خاصيّة password في الصنف User، سيتم توليد دالة ()component4 لها، نسبة لأن ترتيبها هو الرابع في خاصيّات الصنف.

هذا ما تفعله كلمة data تلقائيًا بالأصناف. وبمعرفة ذلك، هل يمكننا تفكيك كائن تم إنشاؤه من صنف عادي وليس صنف بيانات؟ نعم، وكل ما نحتاجه هو تطبيق دالة ()componentN داخل صنفنا.

تفكيك الكائنات بدون كلمة data:

بعد حذف الكلمة المفتاحية data من الصنف User، ومحاولة تفكيك كائن مُنشأ منه، ظهرت الأخطاء التالية في برنامج IntelliJ:

عند وضع مؤشر الفأرة على الخط الأحمر، ظهرت رسالة توضح الخطأ:

Destructuring declaration initializer of type User must have a ‘component1()’ function

Destructuring declaration initializer of type User must have a ‘component2()’ function

Destructuring declaration initializer of type User must have a ‘component3()’ function

الرسالة توضِّح، أنه لاستخدام خاصية تفكيك التصريحات مع الكائن من النوع User، يجب أن يحتوي الصنف على دالة ()componentN.

لحل هذه المشكلة، يمكننا تطبيق الدوال الثلاث داخل الصنف User. بواقع دالة لكل خاصيّة:

نبدأ دالة ()componentN بالكلمة المفتاحية operator ليتم الأخذ بها عند عمل تفكيك للكائن. 

الكلمة operator تعني عامل، مثل عامل الجمع +. إذًا دالة ()componentN هي دالة عامل. وهي تتبع مفاهيم تستخدم بشكل واسع في كوتلن، تعرف بـ principle of conventions. بالرغم من أننا نستخدم الكثير من هذه المفاهيم دون شرحها، سيأتي شرحها تفصيليًا في آخر قسم في هذه الدورة. وعمومًا يمكننا اعتبار ()componentN دالة حاليًا، والتعامل معها على هذا الأساس.

بعد إضافة هذه الدوال للصنف User، يمكن الآن اسناد خاصيّاته لمتغيرات، طبقًا لطريقة تفكيك التصريحات، دون ظهور أية أخطاء.

تفكيك التصريحات مع القوائم وحلقة for:

مع القوائم Lists:

يمكن استخدام تفكيك التصريحات مع القوائم Lists وحلقة for. لأن النوع List، هو صنف يطبق العامل componentN داخله. فمثلًا، إذا كان لدينا قائمة List تحتوي على عدة أنواع من الفواكه، وأردنا طباعة أول ثلاث عناصر في القائمة:

سيتم إسناد أول ثلاث عناصر بالقائمة إلى المتغيرات firstFruit, secondFruit, thirdFruit، بالترتيب. وعند تنفيذ الشفرة، ستكون النتيجة:

مع حلقة for:

فمثلًا، إذا كان لدينا قائمة تحتوي على كائنات من النوع User:

القائمة users تحتوي على كائنين. داخل حلقة for، نستخدم عدد متغيرات بعدد الخاصيّات في كائن User واحد. سيتم تفكيك الخاصيَات الثلاث، وإسنادها إلى المتغيرات، في كل دورة لحلقة for.

الشرطة السفلية للمتغير غير المستخدم:

في الشفرة في الفقرة أعلاه، نلاحظ أنه في كتلة when، نحتاج إلى متغير email فقط لا غير. ولكن إذا حذفنا المتغيرين: username و password، لن تعمل الشفرة. لأنه سيتم إسناد الخاصيّة الأولى للمتغير email. لتجنب ذلك، يمكننا وضع شرطة سفلية، بدلًا عن المتغيرين اللذين لن نستخدمها:

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

وعند تنفيذ الشفرة، سيكون الناتج:

هذا الدرس هو جزء من سلسلة تعليم مبادئ البرمجة بلغة كوتلن. لمُتابعة الدروس منذ البداية ومُشاهدة فهرس المحتويات يمكنك الانتقال إلى الدرس الأول من هنا.

هل أعجبك المحتوى وتريد المزيد منه يصل إلى صندوق بريدك الإلكتروني بشكلٍ دوري؟
انضم إلى قائمة من يقدّرون محتوى إكسڤار واشترك بنشرتنا البريدية.