Menu
Coddy logo textTech

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.

challenge icon

Görev

Kolay

Otomatik 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) bir filename alanına (String) sahip genel bir FileHandle yapısı tanımlayın. Bir FileHandle oluşturan ve dosya "açıldığında" bir mesaj yazdıran bir new ilişkili fonksiyonu uygulayın. Ardından, tutucu bırakıldığında (dropped) bir kapanış mesajı yazdırması için Drop trait'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ıran process_file adlı 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.txt

Ve config.json girdisi ile:

Opening file: config.json
Processing config.json...
Closing file: config.json

Bir 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);
}
quiz iconKendini test et

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