حقائق رئيسية
- إغلاقات Rust هي دوال مجهولة المصدر يمكنها التقاط المتغيرات من نطاقها المحيط، مما يتيح أنماطًا قوية للبرمجة الوظيفية.
- توفير اللغة ثلاثة أنواع مميزة من الإغلاقات — Fn و FnMut و FnOnce — يُعرّف كل منها بالطريقة التي تتفاعل بها مع متغيرات البيئة الملتقطة.
- تستنتج إغلاقات Rust تلقائيًا أنواع المعلمات وقيمة الإرجاع من السياق، على الرغم من أنه يمكن تقديم توضيحات صريحة عند الحاجة للوضوح.
- كلمة المفتاح move تجبر الإغلاقات على أخذ ملكية المتغيرات الملتقطة، مما يجعلها مناسبة للسياقات متعددة الخيوط وضمان صحة البيانات.
- تُستخدم إغلاقات Rust بشكل كبير مع مكرراتها، مما يتيح تحويل البيانات الموجز عبر طرق مثل map و filter و fold.
ملخص سريع
تمثل إغلاقات Rust واحدة من أقوى وأكثر ميزات اللغة مرونة، مما يسمح للمطورين بكتابة كود موجز وتعبيري يلتقط ويتعامل مع البيانات من بيئته المحيطة. على عكس الدوال التقليدية، يمكن للإغلاقات الوصول إلى المتغيرات من نطاقها المحيط، مما يجعلها مثالية للمكالمات العكسية، والمكررات، وأنماط البرمجة الوظيفية.
يستكشف هذا الدليل المفاهيم الأساسية وراء إغلاقات Rust، من صياغتها الأساسية إلى آليات الملكية المتقدمة. من خلال فهم كيفية تفاعل الإغلاقات مع نظام ملكية Rust، يمكن للمطورين كتابة كود أكثر أمانًا وكفاءة، مع تجنب الأخطاء الشائعة المتعلقة بإدارة الذاكرة والإقراض.
صياغة الإغلاق
تستخدم إغلاقات Rust صياغة نظيفة وبديهية تشبه تعريف الدالة ولكن مع اختلافات رئيسية. يتم تعريف الإغلاق باستخدام الأشرطة الرأسية | | لاحتواء معلماته، تليها تعبير أو كتلة تحتوي منطقه. هذه الصياغة الموجزة تجعل الإغلاقات مثالية للاستخدام المضمّن، خاصة مع طرق المكررات.
على سبيل المثال، يمكن كتابة إغلاق يضاعف رقمًا كـ |x| x * 2. هذه الإيجاز هي واحدة من فلسفة تصميم Rust — يجب أن يكون من السهل كتابة قراءة الإغلاقات. على عكس الدوال العادية، لا تحتاج الإغلاقات إلى توضيحات نوع صريحة للمعلمات أو قيم الإرجاع، حيث يستنتجها المترجم من السياق.
ومع ذلك، عندما لا يستطيع المترجم استنتاج الأنواع، يمكن للمطورين تحديدها بوضوح. على سبيل المثال، |x: i32| x * 2 يوضح أن المدخل هو عدد صحيح 32 بت. هذه المرونة تسمح للإغلاقات بالتكيف مع سياقات مختلفة مع الحفاظ على سلامة نوع Rust الصارمة.
القوة الحقيقية للإغلاقات تظهر عندما تلتقط متغيرات من بيئتها. خذ هذا المثال بعين الاعتبار:
- إغلاق يضيف قيمة ثابتة إلى مدخلاته
- يُلتقط الثابت من النطاق المحيط
- يمكن إعادة استخدام الإغلاق مع مدخلات مختلفة
- يحافظ على الوصول إلى المتغير الملتقط
الملكية والإقراض
تتفاعل إغلاقات Rust مع نظام الملكية بطرق دقيقة، مما يحدد ما إذا كانت تنقل أو تُقرض المتغيرات الملتقطة. يُحكم هذا السلوك بتنفيذ الإغلاق وكيفية استخدامه للبيانات الملتقطة. فهم هذه القواعد ضروري لكتابة كود صحيح وفعال.
عندما يأخذ الإغلاق ملكية متغير، فإنه ينقل القيمة إلى الإغلاق، مما يجعل المتغير الأصلي غير متاح بعد ذلك. يحدث هذا عادةً عندما يحتاج الإغلاق إلى ملكية البيانات لضمان بقائها صالحة. على العكس من ذلك، إذا كان الإغلاق يقتضي المتغير فقط، يبقى الأصلي متاحًا خارج الإغلاق.
يحدد المترجم تلقائيًا ما إذا كان يجب النقل أو الإقراض بناءً على كيفية استخدام الإغلاق للمتغير الملتقط. إذا كان الإغلاق يقرأ المتغير فقط، فإنه يقتضيه. إذا احتاج إلى تخزين المتغير أو إرجاعه، فإنه ينقله. يبسط هذا الاستنتاج التلقائي التطوير مع الحفاظ على سلامة الذاكرة.
يمكن للمطورين التحكم في هذا السلوك بوضوح باستخدام كلمة المفتاح move قبل قائمة معلمات الإغلاق. هذا يجبر الإغلاق على أخذ ملكية جميع المتغيرات الملتقطة، وهو مفيد بشكل خاص عند تمرير إغلاقات إلى خيوط أو ضمان بقاء البيانات كافية.
كلمة المفتاح move تضمن أن المتغيرات الملتقطة تمتلكها الإغلاق، مما يمنع الإشارات المعلقة ويجعل الإغلاقات آمنة للخيوط.
أنواع الإغلاق 🎯
تصنف Rust الإغلاقات في ثلاثة أنواع مميزة بناءً على كيفية تفاعلها مع المتغيرات الملتقطة: Fn و FnMut و FnOnce. يمثل كل سمة مستوى مختلف من الوصول والملكية، مما يسمح للمترجم بالتحسين وفرض ضمانات السلامة.
تمثل سمة Fn إغلاقات تقتضي المتغيرات الملتقطة بشكل غير قابل للتعديل فقط. يمكن استدعاء هذه الإغلاقات عدة مرات دون استهلاك البيانات الملتقطة. هي مثالية للعمليات للقراءة فقط، مثل تصفية أو تعيين المجموعات.
على العكس من ذلك، يمكن لإغلاقات FnMut تعديل المتغيرات الملتقطة. تقتضي البيانات بشكل قابل للتعديل، مما يسمح بالتغييرات في البيئة. هذا النوع مفيد للعمليات التي تحتاج إلى تحديث الحالة، مثل تجميع القيم أو تعديل المتغيرات الخارجية.
تُطبق سمة FnOnce على الإغلاقات التي تستهلك المتغيرات الملتقطة. يمكن استدعاء هذه الإغلاقات مرة واحدة فقط لأنها تأخذ ملكية البيانات. هذا النوع ضروري عندما يحتاج الإغلاق إلى إرجاع أو تخزين المتغير الملتقط، مما يضمن عدم استخدام البيانات بعد تنفيذ الإغلاق.
عند تنفيذ هذه السمات، يختار المترجم التلقائيًا الأنسب بناءً على سلوك الإغلاق. يضمن هذا عملية الاختيار أن تكون الإغلاقات مرنة قدر الإمكان مع الحفاظ على قواعد السلامة الصارمة.
- Fn: إقراض غير قابل للتعديل، قابل للاستدعاء عدة مرات
- FnMut: إقراض قابل للتعديل، قابل للاستدعاء عدة مرات
- FnOnce: يأخذ الملكية، قابل للاستدعاء مرة واحدة
التطبيقات العملية
تتألق الإغلاقات في برمجة Rust الواقعية
المكررات هي مثال رئيسي على الإغلاقات في العمل. تقبل طرق مثل map و filter و fold إغلاقات لتحويل أو معالجة المجموعات. على سبيل المثال، استخدام map مع إغلاق يسمح للمطورين بتطبيق دالة على كل عنصر في مجموعة دون كتابة حلقات صريحة.
المكالمات العكسية هي حالة استخدام شائعة أخرى. في البرمجة غير المتزامنة أو الأنظمة القائمة على الأحداث، توفر الإغلاقات طريقة لتحديد السلوك الذي يتم تنفيذه استجابة لأحداث محددة. قدرتها على التقاط السياق تجعلها مثالية للتعامل مع العمليات ذات الحالة.
بالإضافة إلى ذلك، تمكّن الإغلاقات أنماط البرمجة الوظيفية في Rust. من خلال تكوين الإغلاقات، يمكن للمطورين إنشاء خط أنابيب من العمليات تكون كفاءة وتعبيرية. يقلل هذا النهج من الكود النمطي ويعزز قابلية الصيانة.
فكر في السيناريوهات العملية حيث تتألق الإغلاقات:
- تحويل البيانات في مجموعة مع
map - تصفية العناصر بناءً على شروط معقدة
- تنفيذ منطق ترتيب مخصص
- تحديد معالجات الأحداث في تطبيقات واجهة المستخدم الرسومية
النقاط الرئيسية
إغلاقات Rust هي أداة متعددة الاستخدامات تجمع بين قوة الدوال المجهولة المصدر










