سمة Drop
جزء من قسم Object Oriented Programming في رحلة Rust على Coddy — الدرس 56 من 61.
عندما تخرج قيمة عن النطاق (scope) في لغة Rust، يتم تنظيفها تلقائيًا. ولكن ماذا لو كنت بحاجة إلى تشغيل كود مخصص في تلك اللحظة—مثل تسجيل البيانات، أو تحرير مورد، أو إرسال رسالة أخيرة؟ تتيح لك سمة Drop تحديد ما يحدث بالضبط عندما يكون الـ struct الخاص بك على وشك التدمير.
تمتلك سمة Drop طريقة واحدة تسمى drop تأخذ &mut self:
struct Connection {
id: u32,
}
impl Drop for Connection {
fn drop(&mut self) {
println!("Connection {} closed.", self.id);
}
}
لا تقوم أبداً باستدعاء drop مباشرةً—تقوم Rust باستدعائه تلقائياً عندما تخرج القيمة عن النطاق (scope):
fn main() {
let conn = Connection { id: 42 };
println!("Using connection...");
} // "Connection 42 closed." تُطبع هنا تلقائياً
سيكون الناتج:
Using connection...
Connection 42 closed.
هذا هو إصدار لغة Rust للمدمر (destructor). يُستخدم بشكل شائع لمهام التنظيف: إغلاق مقابض الملفات، أو قطع الاتصال بالخوادم، أو تحرير الموارد التي لا تستطيع Rust إدارتها تلقائيًا. تضمن سمة Drop تشغيل كود التنظيف الخاص بك، حتى لو انتهى النطاق بسبب عودة مبكرة.
التحدي
سهللنقم ببناء نظام لإدارة الموارد يوضح التنظيف التلقائي! ستقوم بإنشاء هيكل FileHandle يحاكي فتح وإغلاق الملفات—عندما يخرج المقبض (handle) عن النطاق (scope)، سيعلن تلقائيًا أنه تم إغلاق الملف.
ستقوم بتنظيم الكود الخاص بك عبر ملفين:
file_handle.rs: قم بتعريف هيكلFileHandleعام مع حقلfilenameعام (String). قم بتنفيذ دالة مرتبطةnewتقوم بإنشاء FileHandle وتطبع رسالة عند "فتح" الملف. ثم قم بتنفيذ سمةDropبحيث عندما يتم إسقاط المقبض، فإنه يطبع رسالة إغلاق.main.rs: قم باستيراد وحدة file_handle الخاصة بك وأنشئ دالة تسمىprocess_fileتأخذ اسم ملف، وتنشئ FileHandle داخل نطاق محلي، وتطبع رسالة معالجة بينما الملف "مفتوح". سيتم تشغيل تنفيذ Drop تلقائيًا عند انتهاء النطاق. استدعِ هذه الدالة مع المدخلات المقدمة.
عند إنشاء FileHandle، يجب أن يطبع:
Opening file: {filename}أثناء المعالجة (داخل النطاق)، اطبع:
Processing {filename}...عندما يتم إسقاط FileHandle (ينتهي النطاق)، يجب أن يطبع:
Closing file: {filename}على سبيل المثال، مع المدخلات data.txt:
Opening file: data.txt
Processing data.txt...
Closing file: data.txtومع المدخلات config.json:
Opening file: config.json
Processing config.json...
Closing file: config.jsonستتلقى مدخلاً واحدًا: سلسلة اسم الملف (filename string).
ورقة مرجعية
تسمح لك سمة Drop بتعريف كود تنظيف مخصص يتم تشغيله تلقائيًا عندما تخرج قيمة ما عن النطاق (scope).
تحتوي سمة Drop على طريقة واحدة تسمى drop تأخذ &mut self:
struct Connection {
id: u32,
}
impl Drop for Connection {
fn drop(&mut self) {
println!("Connection {} closed.", self.id);
}
}
لا تقوم أبدًا باستدعاء drop مباشرةً—تقوم لغة Rust باستدعائها تلقائيًا عندما تخرج القيمة عن النطاق:
fn main() {
let conn = Connection { id: 42 };
println!("Using connection...");
} // "Connection 42 closed." تُطبع هنا تلقائيًا
تُستخدم سمة Drop بشكل شائع لمهام التنظيف مثل إغلاق مقابض الملفات، أو قطع الاتصال بالخوادم، أو تحرير الموارد. وهي تضمن تشغيل كود التنظيف الخاص بك، حتى لو انتهى النطاق بسبب إرجاع مبكر.
جرّب بنفسك
mod file_handle;
use file_handle::FileHandle;
// TODO: قم بتنفيذ الدالة process_file
// يجب أن تقوم بـ:
// 1. إنشاء نطاق محلي (باستخدام الأقواس المتعرجة {})
// 2. داخل ذلك النطاق، قم بإنشاء FileHandle باستخدام FileHandle::new()
// 3. طباعة رسالة المعالجة: "Processing {filename}..."
// 4. عند انتهاء النطاق، سيتم استدعاء Drop تلقائياً
fn process_file(filename: &str) {
// TODO: قم بتنفيذ هذه الدالة
}
fn main() {
let mut input = String::new();
std::io::stdin().read_line(&mut input).expect("Failed to read line");
let filename = input.trim();
process_file(filename);
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
1الأساليب والسلوك
مقدمة في كتل التنفيذمعامل Selfالأساليب القابلة للتعديلالدوال المرتبطةكتل تنفيذ متعددةتسلسل الأساليبمراجعة - إجراءات المستطيل4مشروع: حيوان أليف افتراضي
تعريف الحيوان الأليفإطعام الحيوان الأليف2التغليف والوحدات البرمجية
أساسيات الوحدات البرمجيةالكلمة المفتاحية Publicالحقول الخاصةدوال Gettersدوال Settersمراجعة - الخزانة الآمنة5الأنواع العامة (Generics)
الـ Structs العامةالـ Methods العامةأنواع عامة متعددةالـ Functions العامةمراجعة - Coordinate Point3التعدادات المتقدمة (Advanced Enums)
التعدادات مع البياناتالأساليب (Methods) في التعداداتمطابقة حالات البياناتمراجعة التعداد Optionملخص - التعداد Shape6تعريف الـ Traits
ما هي الـ Trait؟تنفيذ الـ Traitsالتنفيذات الافتراضيةتجاوز التنفيذات الافتراضيةالـ Traits مع المعاملاتملخص - مشغل الوسائط