Drop Trait'i
Coddy'nin Rust Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 56 / 61.
Rust'ta bir değer kapsam dışına çıktığında, otomatik olarak temizlenir. Ancak o anda özel bir kod çalıştırmanız gerekirse ne olur—günlük kaydı tutmak, bir kaynağı serbest bırakmak veya son bir mesaj göndermek gibi? Drop trait'i, struct'ınız yok edilmek üzereyken tam olarak ne olacağını tanımlamanıza olanak tanır.
Drop trait'i, &mut self alan drop adında tek bir metoda sahiptir:
struct Connection {
id: u32,
}
impl Drop for Connection {
fn drop(&mut self) {
println!("Connection {} closed.", self.id);
}
}
drop işlevini asla doğrudan çağırmazsınız; değer kapsam dışına çıktığında Rust bunu otomatik olarak çağırır:
fn main() {
let conn = Connection { id: 42 };
println!("Using connection...");
} // "Connection 42 closed." burada otomatik olarak yazdırılır
Çıktı şu şekilde olacaktır:
Using connection...
Connection 42 closed.
Bu, Rust'ın yıkıcı (destructor) versiyonudur. Genellikle temizleme görevleri için kullanılır: dosya tanıtıcılarını kapatmak, sunucularla bağlantıyı kesmek veya Rust'ın otomatik olarak yönetemediği kaynakları serbest bırakmak. Drop özelliği, kapsam erken bir dönüş (return) nedeniyle sona erse bile temizleme kodunuzun çalışmasını garanti eder.
Görev
KolayOtomatik temizlemeyi gösteren bir kaynak yönetim sistemi oluşturalım! Dosyaları açmayı ve kapatmayı simüle eden bir FileHandle yapısı oluşturacaksınız; tutucu (handle) kapsam dışına çıktığında, dosyanın kapatıldığını otomatik olarak duyuracaktır.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
file_handle.rs: Genel (public) birfilenamealanına (String) sahip genel birFileHandleyapısı tanımlayın. Bir FileHandle oluşturan ve dosya "açıldığında" bir mesaj yazdıran birnewilişkili fonksiyonu uygulayın. Ardından, tutucu bırakıldığında (dropped) bir kapanış mesajı yazdırması içinDroptrait'ini uygulayın.main.rs: file_handle modülünüzü dahil edin ve bir dosya adı alan, yerel bir kapsam (scope) içinde bir FileHandle oluşturan ve dosya "açık" iken bir işleme mesajı yazdıranprocess_fileadlı bir fonksiyon oluşturun. Kapsam sona erdiğinde Drop uygulaması otomatik olarak çalışacaktır. Bu fonksiyonu sağlanan girdi ile çağırın.
Bir FileHandle oluşturulduğunda şunu yazdırmalıdır:
Opening file: {filename}İşleme sırasında (kapsam içindeyken) şunu yazdırın:
Processing {filename}...FileHandle bırakıldığında (kapsam sona erdiğinde) şunu yazdırmalıdır:
Closing file: {filename}Örneğin, data.txt girdisi ile:
Opening file: data.txt
Processing data.txt...
Closing file: data.txtVe config.json girdisi ile:
Opening file: config.json
Processing config.json...
Closing file: config.jsonBir girdi alacaksınız: dosya adı dizesi (string).
Kopya kağıdı
Drop özelliği, bir değer kapsam dışına çıktığında otomatik olarak çalışan özel temizlik kodları tanımlamanıza olanak tanır.
Drop özelliği, &mut self alan drop adında tek bir metoda sahiptir:
struct Connection {
id: u32,
}
impl Drop for Connection {
fn drop(&mut self) {
println!("Connection {} closed.", self.id);
}
}
drop metodunu asla doğrudan çağırmazsınız; Rust, değer kapsam dışına çıktığında onu otomatik olarak çağırır:
fn main() {
let conn = Connection { id: 42 };
println!("Using connection...");
} // "Connection 42 closed." burada otomatik olarak yazdırılır
Drop özelliği; dosya tanıtıcılarını kapatmak, sunucu bağlantılarını kesmek veya kaynakları serbest bırakmak gibi temizlik görevleri için yaygın olarak kullanılır. Kapsam erken bir dönüş (return) nedeniyle sona erse bile temizlik kodunuzun çalışmasını garanti eder.
Kendin dene
mod file_handle;
use file_handle::FileHandle;
// TODO: process_file fonksiyonunu uygulayın
// Şunları yapmalıdır:
// 1. Yerel bir kapsam oluşturun (süslü parantez {} kullanarak)
// 2. Bu kapsam içinde, FileHandle::new() kullanarak bir FileHandle oluşturun
// 3. İşleme mesajını yazdırın: "Processing {filename}..."
// 4. Kapsam sona erdiğinde, Drop otomatik olarak çağrılacaktır
fn process_file(filename: &str) {
// TODO: Bu fonksiyonu uygulayın
}
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);
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming bölümündeki tüm dersler
1Metotlar ve Davranış
Uygulama Bloklarına GirişSelf ParametresiDeğiştirilebilir Metotlarİlişkili FonksiyonlarBirden Fazla Uygulama BloğuMetot ZincirlemeÖzet - Dikdörtgen Eylemleri4Proje: Sanal Evcil Hayvan
Evcil Hayvanı TanımlamaEvcil Hayvanı Besleme2Kapsülleme ve Modüller
Modül TemelleriPublic Anahtar KelimesiPrivate AlanlarGetter'larSetter'larÖzet - Güvenli Kasa5Generic Yapılar
Generic Struct'larGeneric MetotlarÇoklu Generic TürlerGeneric FonksiyonlarÖzet - Koordinat Noktası8Sınırlandırıcı Olarak Trait'ler
Trait Sınırlandırıcı SözdizimiÇoklu SınırlandırıcılarWhere CümleciğiTrait'ler ile Tip DöndürmeÖzet - Generic Yazıcı11Rust'ta Tasarım Kalıpları
Newtype KalıbıKompozisyonDrop Trait'iFrom ve IntoÖzet - Smart Pointer Mock3İleri Seviye Enum'lar
Veri İçeren Enum'larEnum MetotlarıVeri Varyantlarını EşlemeOption Enum'ına Yeniden BakışÖzet - Shape Enum6Trait Tanımlama
Trait Nedir?Traitleri UygulamaVarsayılan UygulamalarVarsayılanları Geçersiz KılmaParametreli TraitlerÖzet - Media Player