Drop trait'i, bir kaynağın kapsamdan çıktığında özelleştirilmiş temizlik mantığı belirlemeye olanak tanır. Genellikle dosya, ağ, dış ve güvensiz kaynakların serbest bırakılması için kullanılır. Drop, derleyici tarafından otomatik olarak çağrılır.
Örnek:
struct FileWrapper { fd: i32, } impl Drop for FileWrapper { fn drop(&mut self) { println!("fd'yi kapatıyorum: {}", self.fd); unsafe { libc::close(self.fd); } } } fn main() { let file = FileWrapper { fd: 42 }; } // drop otomatik olarak çağrılır
Özellikler:
file.drop() ile açıkça çağırmak mümkün değildir, ancak std::mem::drop(file) ile çağrılabilir.panic!); bu, "çift panik" ve sürecin acil kapanmasına yol açar.Soru: Bir yapı içindeki drop() işlemi sırasında bir kaynağın mülkiyetini programın başka bir bölümüne geçirmeye çalışırsanız ne olur — örneğin, drop'tan değer döndürmek?
Cevap: Drop sırasında bir yapı alanının değerini, sadece drop’a, başka birine "kurtaramazsınız" veya geçiremezsiniz; bir değeri döndürme veya geçirme girişimi derleme hatası veya bellek güvenliğinin ihlaline yol açar (güvenli olmayan kullanımlarda). Hata örneği:
impl Drop for MyStruct { fn drop(&mut self) -> T { // Hata: Drop::drop bir değer döndüremez! ... } }
Hikaye
Bir dosya işlemcisinde, ham dosya tanımlayıcısını doğrudan saran yapı için Drop uygulamak unutuldu. Yüzlerce işlemden sonra "dosya tanımlayıcıları limiti aşıldı" hatası alındı — kaynaklar temizlenmedi.
Hikaye
Bir ağ kütüphanesinde, TCP bağlantısı için bir sarmalayıcı üzerinde Drop uygulandı, ancak drop sırasında soketin kapanması hatasından dolayı panik meydana geldi. Bu double-panic durumunda iş parçacığının acil kapanmasına yol açtı (tek yol - Drop içinde panikten kaçınmaktır!).
Hikaye
Eklenti sisteminde Drop ile temizlik gerçekleştirilirken, drop sırasında yeni kaynaklar yaratma teşebbüsü (örneğin, bir dosyaya kayıt) yapıldı. Bu, bağlı yapılar için drop’un yenileyici çağrısı yüzünden "zaten ödünç alındı: BorrowMutError" hatasına ve kaynak sızıntısına yol açtı.