تمرير الدوال كوسطاء
جزء من قسم Logic & Flow في رحلة Dart على Coddy — الدرس 45 من 65.
في البرمجة، يمكن للدوال أن تفعل ما هو أكثر من مجرد قبول قيم بسيطة مثل الأرقام أو السلاسل النصية - حيث يمكنها أيضاً قبول دوال أخرى كمعاملات. يُطلق على هذا المفهوم القوي اسم "الدالة من الرتبة العليا" (higher-order function)، وهو يفتح آفاقاً جديدة تماماً لكتابة كود مرن وقابل لإعادة الاستخدام.
عندما تمرر دالة كوسيط، فإنك تمنح دالة أخرى بشكل أساسي القدرة على تحديد العملية التي يجب تنفيذها. فكر في الأمر كأنك تعطي شخصاً ما أداة وتتركه يختار كيفية استخدامها على مواد مختلفة.
void processNumbers(List<int> numbers, Function operation) {
for (int number in numbers) {
operation(number);
}
}في هذا المثال، يأخذ processNumbers قائمة ودالة كمعاملات. معامل الدالة operation يمكن أن يكون أي دالة تقبل عدداً صحيحاً. هذا يعني أنه يمكنك تمرير دالة تطبع الأرقام، أو تضاعفها، أو تقوم بأي عملية أخرى تحتاجها.
هذا النهج يجعل الكود الخاص بك مرنًا للغاية - فبدلاً من كتابة دوال منفصلة لكل عملية ممكنة، تكتب دالة واحدة يمكنها العمل مع العديد من العمليات المختلفة عن طريق قبولها كمعاملات (parameters).
التحدي
سهلأنشئ برنامجًا يوضح تمرير الدوال كوسطاء من خلال بناء معالج أرقام مرن. سيقوم برنامجك بإنشاء دوال معالجة مختلفة وتمريرها إلى دالة معالجة رئيسية تطبق العملية على قائمة من الأرقام.
- اقرأ مدخلاً نصياً يحتوي على أرقام مفصولة بفواصل (على سبيل المثال،
"1,2,3,4,5") - اقرأ مدخلاً نصياً يمثل نوع العملية (
"double"، أو"square"، أو"increment") - قم بتقسيم المدخل الأول إلى قائمة من النصوص وتحويل كل منها إلى عدد صحيح
- أنشئ ثلاث دوال منفصلة:
doubleNumber- تأخذ عدداً صحيحاً وتعيد قيمته مضروبة في 2squareNumber- تأخذ عدداً صحيحاً وتعيد قيمته مضروبة في نفسهاincrementNumber- تأخذ عدداً صحيحاً وتعيد قيمته مضافاً إليها 1- أنشئ دالة رئيسية تسمى
processNumbersتأخذ قائمة من الأعداد الصحيحة ودالة كمعاملات - يجب أن تقوم الدالة
processNumbersبتطبيق الدالة المعطاة على كل رقم في القائمة وإرجاع قائمة جديدة بالنتائج - بناءً على مدخل نوع العملية، قم بتمرير الدالة المناسبة إلى
processNumbers - اعرض النتائج بالتنسيق الموضح أدناه تماماً
على سبيل المثال، إذا كانت المدخلات هي "2,4,6,8" و "double"، يجب أن يخرج برنامجك:
Number Processor
================
Original numbers: [2, 4, 6, 8]
Operation: double
Processing numbers...
Result: [4, 8, 12, 16]
Operation completed successfullyإذا كانت المدخلات هي "3,5,7" و "square"، يجب أن يخرج برنامجك:
Number Processor
================
Original numbers: [3, 5, 7]
Operation: square
Processing numbers...
Result: [9, 25, 49]
Operation completed successfullyإذا كانت المدخلات هي "10,20,30" و "increment"، يجب أن يخرج برنامجك:
Number Processor
================
Original numbers: [10, 20, 30]
Operation: increment
Processing numbers...
Result: [11, 21, 31]
Operation completed successfullyيجب أن يوضح برنامجك مفهوم الدوال العليا (higher-order functions) من خلال تمرير إحدى دوال العمليات الثلاث كوسطاء إلى الدالة processNumbers. استخدم الجمل الشرطية لتحديد الدالة التي سيتم تمريرها بناءً على مدخل نوع العملية. يجب أن تقوم الدالة processNumbers بالتكرار عبر قائمة المدخلات، وتطبيق الدالة المعطاة على كل عنصر، وجمع النتائج في قائمة جديدة.
ورقة مرجعية
الدوال من الرتبة العليا (Higher-order functions) هي دوال يمكنها قبول دوال أخرى كمعاملات، مما يتيح كتابة كود مرن وقابل لإعادة الاستخدام.
لتمرير دالة كوسيط (argument)، قم بتعريف معامل من النوع Function:
void processNumbers(List<int> numbers, Function operation) {
for (int number in numbers) {
operation(number);
}
}يتيح لك ذلك تمرير دوال مختلفة لإجراء عمليات متنوعة على نفس البيانات، مما يجعل الكود الخاص بك أكثر نمطية (modular) ويتجنب الحاجة إلى كتابة دوال منفصلة لكل عملية محتملة.
جرّب بنفسك
import 'dart:io';
void main() {
// قراءة المدخلات
String? numbersInput = stdin.readLineSync();
String? operation = stdin.readLineSync();
// تحويل المدخلات النصية إلى قائمة من الأعداد الصحيحة
List<int> numbers = numbersInput!.split(',').map((e) => int.parse(e.trim())).toList();
// TODO: (doubleNumber, squareNumber, incrementNumber) قم بإنشاء دوال العمليات الثلاث
// TODO: التي تأخذ قائمة ودالة كمعاملات processNumbers قم بإنشاء دالة
// TODO: استخدم العبارات الشرطية لتحديد الدالة التي سيتم تمريرها بناءً على نوع العملية
// TODO: مع الدالة المناسبة وقم بتخزين النتيجة processNumbers قم باستدعاء
// طباعة النتائج بالتنسيق المطلوب
print('Number Processor');
print('================');
print('Original numbers: $numbers');
print('Operation: $operation');
print('Processing numbers...');
// TODO: اطبع قائمة النتائج هنا
print('Operation completed successfully');
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Logic & Flow
1التعامل المتقدم مع القوائم
خصائص القائمة: first و lastحالة القائمة: isEmpty و isNotEmptyعكس القائمةالإضافة إلى القائمة: insertالحذف من القائمة: removeWhereالبحث في القائمة: indexOfفرز القائمةخلط القائمةملخص - منظم القوائم4معالجة الـ Map المتقدمة
التكرار عبر الـ Mapالتحقق من المفاتيح والقيمخصائص الـ Map: keys و valuesإضافة مشروطة: putIfAbsentإزالة العناصر من الـ Mapالـ Maps المتداخلةمراجعة - تحديث المخزون2عمليات القوائم الوظيفية
التحويل باستخدام 'map'التصفية باستخدام 'where'استخدام '.toList()'التحقق من الشروط باستخدام 'any'الشروط باستخدام 'every'البحث باستخدام 'firstWhere'مراجعة - تصفية البيانات5مشروع: حاسبة عربة التسوق
إعداد المشروعإضافة العناصر إلى العربة3المجموعات
ما هي المجموعة؟إنشاء مجموعةالإضافة والحذف من المجموعاتالتحقق من وجود عناصر في المجموعةتحويل قائمة إلى مجموعةاتحاد المجموعاتتقاطع المجموعاتالفرق بين المجموعاتمراجعة - قائمة ضيوف فريدة