تعلّم البرمجة بلغة كوتلن (13): الدوال Functions

تعلّم البرمجة بلغة كوتلن (13): الدوال Functions
أستمع الى المقال

شرحنا في درس مرحبًا بالعالم !Hello, World دالة الـ main، والتي تعتبر هي المدخل الرئيسي لأي برنامج مكتوب بلغة كوتلن. وقلنا أن هناك العديد من الدوال في كوتلن، التي تقوم بوظائف متعددة. واستخدمنا دالتين من هذه الدوال، وهما دالتي الطباعة ()print و ()println.

في هذا الدرس، سنتعرف على الدوال في البرمجة، وكيف يمكننا إنشاء دالة خاصة بنا غير تلك التي توفرها لنا مكتبة كوتلن القياسية، ولماذا نحتاج إلى استخدام الدوال أساسًا.

ما هي الدالة Function:

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

تحتوي مكتبة كوتلن القياسية على الكثير من الدوال التي يمكننا استدعاؤها للقيام بالكثير من المهام، مثل دالة ()println. إذا لم تكن دوال كوتلن كافية أو مناسبة لبرنامجنا، يمكننا إنشاء دالة جديدة ثم استدعائها بنفس طريقة استدعاء الدوال من مكتبة كوتلن القياسية.

مفهوم تقسيم الشفرة decomposition:

تعمل الدوال على تقسيم البرنامج إلى أجزاء صغيرة قابلة لإعادة الاستخدام. يطلق عليها مصطلح decomposition. يمكننا استدعاء هذه الأجزاء (الدوال) عدة مرات كما نريد، بدلاً من تكرار نفس الشفرة كل مرة. يعد البرنامج المقسم بهذه الطريقة، سهل التعديل والصيانة أكثر بكثير من برنامج يتكون من دالة رئيسية main واحدة تحتوي على ألف سطر. تأخذ كوتلن هذا المفهوم من البرمجة الإجرائية procedural programming.

إنشاء دالة:

يجب أن تبدأ الدالة بالكلمة المفتاحية fun، وأن يكون للدالة اسم خاص بها، ويتم تنفيذها (أو استدعاؤها invoke) بواسطة استدعاء هذا الاسم من دالة أخرى. وأيضا المعاملات Parameters، ونوع بيانات القيمة التي تعيدها الدالة. ثم داخل الأقواس المعقوفة، سلسلة التعليمات البرمجية وفي آخر سطر الكلمة المفتاحية return. كالتالي:

عند النظر إلى الشفرة أعلاه، نجد أن الدالة تتكون من:

  • اسم الدالة، والذي نتبع فيه نفس المعايير والقواعد التي نتبعها عند إنشاء متغير والتي ذكرناها في درس المتغيرات والقيم بالتفصيل.
  • بين القوسين يمكننا وضع المعاملات Parameters إذا كانت الدالة تحتاجها للقيام بعملها. يجب أن نضع لكل معامل اسم ثم نقطتين ( : ) ثم نوع هذا المعامل إذا كان Int أو String أو Boolean أو غيرها من أنواع البيانات. ويجب أن نفصل بين المعاملات بفاصلة ( , ).
  • بعد القوسين، نضع نقطتين ( : ) ثم نوع القيمة التي ستعيدها الدالة ReturnType، مثل: Int إذا كانت تعيد قيمة عددية و String للقيمة النصية … الخ. هذه الخطوة اختيارية، إذا كانت الدالة ستعيد قيمة من نوع Unit.
  • بين الأقواس المعقوفة، نضع سلسلة التعليمات البرمجية للدالة.
  • الكلمة المفتاحية return، إذا كانت الدالة ستعيد نتيجة. ويجب أن تكون هذه الكلمة في السطر قبل قوس الإغلاق للدالة، لأن كل سطر تحت هذه الكلمة لن يتم تنفيذه. يمكن الاستغناء عن هذه الكلمة، إذا كانت الدالة ستعيد قيمة من نوع Unit.

النوع Unit، ستعيده الدالة إذا كانت لا تعيد أي قيمة من نوع بيانات آخر. كمثال لدينا من دوال كوتلن، الدالة الرئيسية ()main التي يبدأ منها البرنامج ولا تحتاج إلى إعادة قيمة و دالة الطباعة ()println والتي مهمتها طباعة المدخلات فقط. عندما ننشئ دالة لا تعيد قيمة، يمكننا كتابة Unit كـ ReturnType، أو عدم كتابتها كما فعلنا مع دالة main، لأن كوتلن ستضعها افتراضيًا إذا لم نضع نوع الإرجاع صراحةً.

المعاملات Parameters وقيمة المعامل Argument:

يمكننا إنشاء دالة تأخذ معامل واحد أو معاملات كثيرة من نفس النوع أو من أنواع بيانات مختلفة. وعند استدعاء هذه الدالة، يجب أن ندخل قيمة Argument لهذا المعامل أو المعاملات.

كمثال، إذا أردنا إنشاء دالة تقوم بجمع رقمين وإعادة نتيجة الجمع، فستكون كالتالي:

مهمة الدالة التي نريدها منها هي الجمع، لذا اسميناها اسم مناسب وهو sum، والذي يعني (جمع) باللغة الإنجليزية. نريد من الدالة أن تجمع رقمين أو عددين صحيحين فقط، لذا وضعنا لها معاملين a , b، من النوع Int. وحددنا نوع القيمة التي ستعود بعد عملية الجمع، بوضع ( Int : ). ثم قمنا بالعملية الأساسية للدالة وهي الجمع وإسناد النتيجة إلى متغير أسميناه result. وفي آخر سطر الكلمة return والتي تعني حرفيًا أعِد، أي أعِد نتيجة المتغير result.

لتنفيذ هذه الدالة يجب أن نستدعيها في دالة الـ main، كالتالي:

عند استدعاء الدالة sum، يجب وضع قيم Arguments عددية صحيحة من نوع Int لمعامليها. ولأن الدالة sum ستعيد نتيجة جمع الرقمين، يمكننا تخزين هذه النتيجة في متغير داخل الدالة main. الآن بعد أن أصبح المتغير يحمل قيمة جمع الرقمين، يمكننا إرساله لدالة الطباعة ()println لطباعة قيمته.

وبالطبع يمكننا زيادة المعاملات للدالة كما نريد، إذا أردنا جمع أكثر من رقمين، كالتالي:

وعند استدعاء الدالة بعد هذا التعديل، أصبح من اللازم إرسال 4 قيم للمعاملات، ولم تعد الدالة تقبل رقمين كالسابق، كالتالي:

هذا لن يشكل مشكلة، إذا كنا نحتاج في مكان ما في شفرة البرنامج جمع 4 أرقام. ولكن ستحدث المشكلة إذا أردنا إعادة استخدام الدالة في مكان آخر في شفرة البرنامج لجمع رقمين فقط. هل علينا كتابة الدالة مرتين، مرة بـ 4 معاملات، ومرة أخرى بمعاملين؟

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

ما هي المعاملات ذات القيم الافتراضية Default arguments:

هي طريقة لكتابة معاملات دوال اختيارية، بوضع قيمة افتراضية مسبقًا. يمكن لمن يستدعى دالة من هذه الدوال، وضع قيم تناسب المعاملات أو تركها. للتوضيح أكثر، يمكننا التعديل مرة أخرى، على دالة sum كالتالي:

وضعنا قيمة افتراضية صفر، لآخر معاملين في الدالة c و d، فبالتالي أصبحا اختياريين. وتركنا أول معاملين ليكونا اجباريين، لأن دالة sum، تحتاج على الأقل رقمين. والآن يمكن استدعاء هذه الدالة، كالتالي:

كما نرى في الشفرة أعلاه، استخدمنا دالة sum ثلاث مرات. في المرة الأولى، ستجمع الدالة 5 + 3 + 0 + 0. وفي المرة الثانية، 5 + 3 + 4 + 0. وفي المرة الثالثة، 5 + 3 + 4 + 9.

هذا لأن كوتلن ستعوض المعامل الذي لم يتم ارسال قيمة له بقيمته الافتراضية. وهذا يبرز أيضًا بعض قوة استخدام الدوال Functions في لغة كوتلن. حيث مكنتنا من القيام بالمهمة، بأقل شفرة ممكنة.

قيم المعاملات المسماة Named Arguments:

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

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

لحساب ذلك، فلنفترض أننا نحتاج إلى دالة ذات ثلاث معاملات من النوع Int. معامل لإدخال المال الذي كان في الصندوق قبل البدء في البيع وليكن اسمه startAmount، ومعامل ثاني لحساب عدد القطع التي تم بيعها soldProducts، وثالث لسعر القطعة الواحدة productPrice. ومن ثم ستقوم الدالة بضرب عدد قطع المنتج في سعره وجمع الناتج بالمال الذي كان في الصندوق. كالتالي:

وعندما استدعينا هذه الدالة وضعنا القيم بهذه الطريقة:

ليس من الواضح مباشرة أي المعاملات تمثل هذه القيم. وسنترك المهمة لكوتلن لتكتشف قيمة كل معامل بنفسها. ولكن يمكننا زيادة قابلية القراءة للشفرة أعلاه، بذكر أسماء المعاملات صراحة عند استدعاء الدالة، كالتالي:

دوال Single-expression:

هي طريقة لكتابة الدوال بأقل شفرة ممكنة. عند استخدام هذه الطريقة، يمكننا إعادة كتابة دالة sum لتكون عبارة عن سطر واحد فقط، كالتالي:

كما نرى، سمحت لنا كوتلن بحذف الكثير من الشفرة وما زالت تؤدي مهمتها كالسابق. ليس هذا وحسب، بل يمكننا أيضًا حذف نوع القيمة التي تعيدها الدالة، كالتالي:

ستستدل كوتلن على نوع القيمة المعادة، من التعبير الرياضي يمين علامة الإسناد.

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

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

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