هل ترغب في تعلم المزيد عن Scala؟ اخبر بتخصص دورة DataCamp المقدمة تعلم Scala.
Scala لغة برمجية تعمل بالطريقة الوظيفية حيث تحتوي كل من المتغيرات المفاعلية والطرق ولكن لديها أيضًا أشياء متشابهة وغير متشابهة. كلا المتغيرات والطرق هي قطعة من الشيء التي يمكن تجديدها ويستخدم لتخزين الشيء المكرر في مكان واحد وهذا ما يجعل من طريقة اتصال مع الدالة للقيام بمهمة معينة. إضافة إلى أنهم يجعل الكود أسهل على التصحيح والتعديل.
ومع ذلك فإن المتغيرات هي جهة تم تكوينها في المتغير، لكن الطرق تبدأ بالكلمة ‘def’ متتاليةً باسم الطريق وقائمة المعاملات وجسم الطريق مع القيمة المعودة.
إعلان الطريق وتعريفه
النموذج لإعلان وتعريف الطريق في Scala هو ما يلي:
def 'method_name' ('parameters':'return_type_parameters') : ('return_type_of_method') = { 'method_body' return 'value' }
يبدأ الطريق في أجزاء من التالي:
- ‘def’: الكلمة المستخدمة لإعلان الطرق.
- ‘method_name’: اسم ما تسمي معه الطريقة، وهي بحروف الجنوب المجاورة.
- ‘parameters’: معاملات الطريق التي قد لا تحتوي على معاملة أو تحتوي على معاملة واحدة فقط ولكنهم يفصلون بعلامة ال逗号 عندما يكون هناك معاملة أكثر من واحدة.
- ‘return_type_of_parameters’: يتوجب توافقه مع نوع قيمة ‘parameters_list’ وهو من المطابق.
- ‘return_type_of_method’: هو خياري، ومع ذلك في الافتراض، يتم إرجاع ‘Unit’, لكن قد يحصل على قيمة يمكن إرجاعها بواسطة كلمة المفاعل ‘return’.
- علامة التعيين (‘=’): هي خيارية، وإن تم استخدامها سيتم تعيين قيمة الإرجاع وإذا لم يتم استخدامها سيصبح المétodo بدون أي إرجاع.
- ‘body_of_method’: هي قطعة الكود المحاصرة داخل التعايير الكاملة ‘{}’ وتتكون من المنطق المطلوب أو المهمة أو العمليات.
- return: هي كلمة المفاعل التي يستخدم لإرجاع القيم المطلوبة وتوقف البرنامج ولكنها نادرة في Scala.
مهمة الدعوة
النموذج للمهمة الدعوية في Scala هو أساسًا:
method_name(arguments)
يمكن إجراء مهمة الدعوة بسرعة بواسطة ‘method_name’, وهو اسم المهمة التي تريد أن تدعو مع المعاملات التي تم تقديمها.
مهمة ذات المعاملات المعنية
المهمة التي تتضمن المعاملات المعنية ستسمح للمعاملات التي تم تقديمها أثناء دعوة المهمة بأن تتم تعيين كل معامل بما يتطلب معها المتغيرات. سترى مثالًا أدناه لتقديم المعاملات مع إعلان الوظيفة وتعريفها ومع دعوة المهمة في عمل:
object calculateResult { def funSub(x:Int, y:Int) : Int = { var diff:Int = 0 diff = x - y // return value return diff } def main(args: Array[String]) { // Function call println("Difference of the value is: " + funSub(8,6)); println("Difference of the value is " + funSub(y=6,x=8)); } }
ستنتج البرنامج الأعلى نتيجة كما تلوحظ:
فارق القيمة هو: 2
فارق القيمة هو: 2
لديك برنامج يحتوي على جسم ‘calculateResult’، وداخله يوجد طريقة تسمى ‘funSub’ وتحتوي على المعطيات x و y ويسترجع النوع ‘Int’، نوع العودة الكلي للطريقة هو ‘Int’. وما بعدها تعيين إجراء لتعيين قيمة العودة. الأقوال الكرويه تشير إلى بداية جسم الطريقة، حيث يُبدأ المتغير ‘diff’ بالقيمة الإبتدائية 0. استدعاء الطريقة ‘funSub(8,6)’ الذي يجري في الطريقة الرئيسية يطابق 8 بـ ‘x’ و6 بـ ‘y’، ويجري عملية الخصم، ويُعاد قيمة ‘diff’ وفي النهاية يتم طباعتها. وبشكل مماثل، ‘funSub(x=8,y=6)’ يطابق 6 بـ ‘y’ و8 بـ ‘x’ للمعطيات في الطريقة أثناء استدعاء الطريقة حيث لا يهم الترتيب، ويتم عمل عملية مماثلة ويُعاد ويتم طباعته.
القيم الافتراضية للمعطيات
يمكنك تحديد القيم الافتراضية لمعطيات الطريقة من خلال تهيئة القيم المقابلة ويمكنك ترك استدعاء الطريقة فارغاً بعدم إرسال ال인جز.
object calculateResult { def funSub(x:Int=9, y:Int=6) : Int = { var diff:Int = 0 diff = x - y // return value return diff } def main(args: Array[String]) { // Function call print( "The final value is: " + funSub() ); } }
يعطي البرنامج أعلاه الناتج كالتالي:
القيمة النهائية هي: 3
يمكنك رؤية البرنامج أعلاه يحتوي على كائن معرف باسم ‘calculateResult’ وداخله يوجد دالة تسمى ‘funSub’ مع المعاملات x و y وكلاهما له نوع إرجاع ‘Int’ والنوع العام لإرجاع الدالة هو ‘Int’ ويليها عبارة تعيين ستعين قيمة الإرجاع. الأقواس المعقوفة تشير إلى بداية جسم الدالة، حيث يتم تهيئة المتغير ‘diff’ بالقيمة الأولية 0. يتم استدعاء الدالة من داخل الدالة الرئيسية حيث يتم استدعاء ‘funSub()’ وتعيين x إلى 9 و y إلى 6، ويتم تنفيذ العملية، مما يجعل قيمة ‘diff’ يتم إرجاعها وطباعتها.
المعطيات ذات الطول المتغير
المعطيات ذات الطول المتغير هي المعطيات التي تأخذ أي عدد متغير من المعطيات ويمكن تمريرها من قبل المستخدم أو العميل. يتم إعلان المعامل الأخير في الدالة باستخدام ‘*’ والذي يحتاج إلى تكرار.
object variableArgument { def main(args: Array[String]) { printAll("Scala", "is", "great") } def printAll(strings: String*) { var i : Int = 0; for( value <- strings ){ println(value); i = i + 1; } } }
البرنامج أعلاه يعطي المخرجات كالتالي:
Scala
is
great
يمكنك رؤية البرنامج أعلاه يحتوي على كائن ‘variableArgument’ مع دوال ‘printAll’ حيث يتم تعريف المعطيات ذات الطول المتغير ‘String*’ في النهاية وخلال استدعاء الدالة يمكن تمرير قائمة من السلاسل النصية. يتم تكرار القائمة الممررة من السلاسل النصية وعرضها كمخرج داخل الدالة الرئيسية.
دالة الاستدعاء الذاتي
تتم استخدام التكرارية كتقنية في البرمجة الوظيفية حيث يتم حل المشكلة بتكرار تقسيمها إلى مشاكل أصغر، والتي تشبه المشكلة الأصلية. حل المشاكل الأصغر وتطبيق حلولها للحصول على حلول للمشكلة الأصلية. إذاً، تسمى بالتقسيم-والاستغلال أو التقليل-والاستغلال، وهذا يجعل الكود أنظف وأنيق. عند كتابة دالة تكرارية، يجب الاعتبار الشيئين التاليين بصرامة:
- الحالة الأساسية: قد يكون هناك أكثر من حالة أساسية واحدة في الدالة التي يتوجب إيجادها وإلا قد يؤدي إلى تكرار لا نهائي. يحتاج إلى حل، أي الشكل البسيط من الخرج أو الحل التي يمكن تحقيقها بدون تكرار.
- الحالة التكرارية: الحالة التي يتم تطبيق الدالة التكرارية، أي يتم إجراء مكالمات تكرارية. الجوهر الأساسي للمشكلة هو أنه في كل مكالمة تكرارية، يجب أن يتم تقليل الحجم، أي يتوجب تقسيم المشكلة إلى مشاكل أصغر حتى تصل إلى الحالة الأساسية. في النهاية، تجمع الحلول للحصول على المشكلة الرئيسية، وهذا يسمى بمنهج التقسيم والاستغلال.
عدد الفاكتوريال لأي عدد معطى هو n! يمكن تعبيرها رياضيا كما يلي:
أيضًا، يمكنك جعل العبارات (n-1).(n-2)…3.2.1 تكون (n-1)! لذلك، عدد الفاكتوريال لأي عدد معطى هو دائما n. (n-1)!
الآن يمكنك أن ترى أسفل الطريقة التكرارية لحل المشكلة.
object factorialDemo { def main(args: Array[String]) { for (i <- 1 to 5) println( "Factorial of " + i + ": = " + factorial(i) ) } def factorial(n: Int): Int = { if (n <= 1) return 1 else return n * factorial(n - 1) } }
النص بعد الترجمة إلى اللغة العربية:
فاكتوريال من 1: = 1
فاكتوريال من 2: = 2
فاكتوريال من 3: = 6
فاكتوريال من 4: = 24
فاكتوريال من 5: = 120
يمكنكم أن تروا أعلاه حيث يوجد شئ يُدْعى ‘factorialDemo’ وداخله، يوجد ‘main’ تابع يحتوي على دائرة تكرر لمرات خمسة ويشمل أيضًا استدعاء تابع لـ ‘factorial’ حيث يقوم الوظيفة التدريجية بتدريجي، أي، n مرة خمسة. يتوقف عند حالة القاعدة عندما يصبح n أقل من أو يساوي 1، ويُرجع النتيجة ويُطبع.
الوظيفة الغير المسماة
الوظيفة الغير المسماة هي تعريف الوظائف الخفيفة التي لا تمتلك اسم وتعرف بـ كتلة الوظيفة في Scala.
أسلوب ومثال للوظيفة الغير المسماة هو كما يلي:
- أول أسلوب ومثال للوظيفة الغير المسماة هو:
الأسلوب:
('first_variable':'data_type', 'second_variable':'data_type') => "certain_expression"
المثال:
(var1:String:var2:String) => var1 + var2
أو
- الأسلوب الثاني ومثال للوظيفة الغير المسماة هو:
الأسلوب:
(_:'data_type')operator(_'data_type')
المثال:
(_:String)+(_:String)
يُظهر الأسلوب الأول أن التعبير بعد “=>” يُقيَّم إلى قيمة محددة بينما يستخدم القائمة من المتغيّرات قبل “=>” لتقييم التعبير.
يعمل الأسلوب الثاني أعلاه كرمز محفز حيث يقبل القيمة كـ ‘رمز البرية’ مرة واحدة فقط، ومن ثم يتم إجراء العملية بينهم.
plaintext
ستشاهد مثالاً للوظيفة الغير مسماة أدناه:
object anonymousDemo { def main(args: Array[String]) { var function1 = (var1:Int, var2:Int) => var1 + var2 var function2 = (_:Int) + (_:Int) // function call println(function1(5, 5)) println(function2(7, 3)) } }
Initializing Scala interpreter ... Spark Web UI available at http://DESKTOP-03TH7J0:4040 SparkContext available as 'sc' (version = 2.4.3, master = local[*], app id = local-1566986265958) SparkSession available as 'spark' <console>:10: error: unbound placeholder parameter var function2 = {_:Int} + {_:Int} ^ <console>:10: error: unbound placeholder parameter var function2 = {_:Int} + {_:Int} ^
البرنامج أعلاه يعطي الخرج كما يلي:
10
10
يمكنكم أن تروا أن المخلوق المسمى ‘anonymousDemo’ ويحتوي على الوظيفة ‘main’ التي تحتوي على وظيفتين غير مسميتين. إنهما تتمايزان سيntaxياً لكن يمكن أن تنتج نفس النتيجة، حيث تقوم ‘function’1 بتقييم باستيراد المعطيات من نداء الوظيفة كما تم إتصال بها — تمرر القيم 5 و5، والتي تنتج الخرج ليتم الطباعة كـ 10 بينما ‘function2’ تم إتصال بها أيضًا بمرور 7 و3 حيث تتلقى القيمة مرة واحدة، التي تقبل أي ‘Integer’ صالح. في حالتكم، قم بعملية الإضافة وأعطي النتيجة.
الخاتمة
تهانينا، لقد أنتهيتم من قراءة هذا الدرس التوجيهي.
هناك العديد من المواضيع المتقدمة في Scala، مثل الوظائف العالية الطبقة، الوظائف الضمنية، وظيفة التجميع، إلخ.
المرجع:
جولة أساسات Scala
Scala | الوظائف – الأساسيات
Scala – الوظائف
وظائف غير مسماة في Scala
أنظر إلى دورة DataCamp مقدمة لـ Scala.
Source:
https://www.datacamp.com/tutorial/basic-functions-methods-scala