ویژگی Drop
مقادیر که ویژگی Drop را پیادهسازی میکنند میتوانند کدی را مشخص کنند که هنگام خروج از دامنه اجرا شود:
struct Droppable { name: &'static str, } impl Drop for Droppable { fn drop(&mut self) { println!("Dropping {}", self.name); } } fn main() { let a = Droppable { name: "a" }; { let b = Droppable { name: "a" }; { let c = Droppable { name: "c" }; let d = Droppable { name: "d" }; println!("Exiting block B"); } println!("Exiting block A"); } drop(a); println!("Exiting main"); }
This slide should take about 8 minutes.
- توجه داشته باشید که
std::mem::dropباstd::ops::Drop::dropیکسان نیست. - مقادیر به طور خودکار زمانی که از دامنه خارج میشوند، حذف میشوند.
- زمانی که یک مقدار حذف میشود، اگر آن مقدار ویژگی
std::ops::Dropرا پیادهسازی کرده باشد، پیادهسازیDrop::dropآن فراخوانی خواهد شد. - تمام فیلدهای آن نیز سپس حذف خواهند شد، چه آن مقدار ویژگی
Dropرا پیادهسازی کرده باشد یا نه. std::mem::dropیک تابع خالی است که هر مقداری را میپذیرد. اهمیت آن در این است که مالکیت مقدار را به عهده میگیرد، بنابراین در پایان دامنهاش حذف میشود. این ویژگی آن را به روشی مناسب برای حذف صریح مقادیر پیش از آنچه که معمولاً از دامنه خارج میشوند، تبدیل میکند.- این میتواند برای اشیائی که در هنگام
dropکاری انجام میدهند مفید باشد: آزاد کردن قفلها، بستن فایلها و غیره.
- این میتواند برای اشیائی که در هنگام
نکات بحث:
- چرا
Drop::dropselfرا نمیگیرد؟- پاسخ کوتاه: اگر اینطور بود،
std::mem::dropدر پایان بلوک فراخوانی میشد که منجر به فراخوانی مجددDrop::dropو ایجاد خطای سرریز (stack overflow) stack میشد!
- پاسخ کوتاه: اگر اینطور بود،
- سعی کنید
drop(a)را با()a.dropجایگزین کنید.