تعلّم البرمجة بلغة كوتلن (42): وظائف إضافية لـ Nullable Types

تعلّم البرمجة بلغة كوتلن (42): وظائف إضافية لـ Nullable Types
أستمع الى المقال

رأينا في درس الوظائف الإضافية، كيف يمكننا إلحاق دوال بـ أنواع البيانات الأساسية في كوتلن، أو حتى لـ الأصناف من المكتبات التي ندمجها في تطبيقنا، ولا نستطيع تعديلها أو تحريرها.

هذه الأنواع والأصناف التي شرحناها في درس الوظائف الإضافية، كانت من النوع الافتراضي، والذي لا يقبل قيم فارغة Non-Nullable Type. أمّا في هذا الدرس، سنرى كيف نضيف وظائف إضافية، للأنواع التي تقبل قيم فارغة Nullable Type عبر إنشاء دوال ملحقة لها.

استخدام خاصيّات ودوال من النوع Non-Nullable:

توفر كوتلن خاصيّات خاصة بالنوع Non-Nullable، مثل الخاصيّة length، لنوع البيانات String. ودوال عضوة بالصنف Member Functions مثل دالة ()get، والتي تعيد الحرف الذي يُمثل الفهرس المرسل إليها، وغيرها من الخاصيّات والدوال.

وعند استخدام هذه الخاصيّات والدوال مع النوع الثاني Nullable، يجبرنا مترجم كوتلن، على أن نستخدم عامل الإستدعاء الآمن (.?)، حتى يتم تجنب تحطم البرنامج، كما شرحنا في الدرسين السابقين. 

فمثلًا، إذا كنا نريد معرفة عدد أحرف نص ?String، سنستخدم الخاصيّة length:

val x: String? = null

x?.length

بالطبع، عند قراءة هذه الشفرة لاحقًا، سنعرف تلقائيًا أن المتغير x، هو من النوع Nullable لوجود العامل (.?). وبنفس الطريقة، لن نستطيع استدعاء أي دالة مثل ()get على المتغير x، بدون أن نضع عامل الإستدعاء الآمن هذا.

استخدام دوال ملحقة بالنوع Nullable:

لدينا في مكتبة كوتلن القياسية، بعض الدوال الملحقة بالنوع Nullable. منها على سبيل المثال، دالتي:

  • ()isNullOrEmpty: تعمل على فحص ما إذا كان النص الذي استدعاها، يحمل القيمة null أو فارغ empty. ستعيد القيمة true إذا كان كذلك.
  • ()isNullOrBlank: نفس العمل مثل ()isNullOrEmpty. مع الاختلاف أنها حتى في وجود مسافات فارغة، ستعيد نتيجة أن النص فارغ، أي القيمة true.

الشفرة التالية، ستوضح عمل الدالتين وما نريد توضيحه بذكرهما في هذا الدرس:

لدينا في الشفرة، ثلاث متغيرات: s1 وهو متغير من النوع ?String، ويُمثل القيمة null. ومتغير s2 من النوع String ويُمثل قيمة نص فارغ “”. ومتغير s3 وبه مسافة فارغة.

استخدمنا الدوال مع النوعين Nullable و Non-Nullable، دون أي إحتجاج من المترجم، وسيتم تنفيذ البرنامج عادي:

لم نستخدم العامل (.?) عند استدعاء الدوال مع النوع Nullable والذي يُمثله المتغير s1، لأن الدالتين هما دوال ملحقة بالنوع ?String، لذا لا نحتاج إلى استخدام عامل الاستدعاء الآمن، فقد تم بناء الدالتين أساسًا لتجنب مشكلة الـ null، خلاف الدوال في النوع الافتراضي String.

وهذا قد يسبب مشكلة لاحقًا، عند محاولة قراءة الشفرة. لأنه في هذه الحالة، لا يمكننا معرفة ما إذا كان المتغير أو الكائن الذي تم استخدام الدوال الملحقة بالنوع ?String، من النوع Nullable أم من النوع Non-Nullable.

لذا عند إلحاق دوال بالنوع ?String، يجب أن نكون حذرين ونجعل أسماء هذه الدوال تشرح نفسها. مثل الدالتين السابقتين، واللتين من الواضح أنهما للنوع Nullable، لأنهما تحتويان على الكلمة null في إسميهما.

إلحاق دالة بالنوع Nullable:

تمامًا كما فعل فريق كوتلن بإلحاق دوال بالنوع Nullable، يمكننا أيضًا فعل المثل. فقط يجب أن نهتم، بأن يكون عملها والنوع المستقبل الذي تُمثله، واضحًا في إسمها بقدر الإمكان:

ألحقنا دالة ()nullToString بالصنف الأعلى لكل الأنواع والأصناف من النوع Nullable الصنف ?Any. كما يتضح من إسم الدالة، نحن نريد استخدامها في طباعة رسالة نصية مخصصة، عندما يكون الكائن الذي يستدعيها Receiver Type، من النوع Nullable.

ستفحص الدالة قيمة الكائن الذي استدعاها، ثم بمساعدة من العامل Elvis (:?)، ستقوم بإعادة قيمة الكائن إذا لم تكن null، أو إعادة الرسالة يمين العامل. وهذه هي طريقة عمل العامل Elvis كما شرحنا في الدرس السابق.

ولأننا أضفنا هذه الدالة للصنف ?Any، يمكننا استخدامها مع كل الأصناف الخاصة بنا، أو حتى الأنواع في كوتلن. مثل:

String?, Boolean?, Char?, Int?, Long? …etc.

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

بالطبع، يُمكننا أيضًا استخدام هذه الدالة مع الأنواع التي لا تقبل قيم فارغة Non-Nullable Types. وإن كان ليس من المنطقي فعل ذلك، لأنه لن تسمح كوتلن بتاتًا، بإضافة القيمة null لهذه الأنواع. لذا بدلًا عن ذلك، بكل بساطة يمكننا إلحاق دالة بالأصناف من هذا النوع.

الخلاصة:

الدوال الملحقة للأنواع Nullable. قد تكون مفيدة للحالات البسيطة، مثل ما فعل فريق كوتلن بإضافة دالتي ()isNullOrEmpty و ()isNullOrBlank، ومثلما فعلنا نحن بإضافة دالة ()nullToString. 

ولكن يجب أن نتوخى الحذر عند استخدام هذه الميزة. ونضيف الأسماء التي تشرح نفسها بنفسها، والتي تشير إلى أن الكائن الذي يستدعي الدالة Receiver Type، قد يكون من النوع Nullable. 

وبشكل عام، من الأفضل الإعلان عن دوال ملحقة عادية (للأنواع التي لا تقبل قيم فارغة Non-Nullable Types). ثم عند استخدامها مع الأنواع Nullable، سيجبرنا مترجم كوتلن، على استخدام عامل الاستدعاء الآمن (.?). هكذا، سيكون من السهل على الشخص الذي يقرأ شفرتنا، أو حتى نحن إذا رجعنا للشفرة الخاصة بنا بعد عدة أشهر مثلًا، أن نفهم أن هذا الكائن من النوع Nullable.

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

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