Menu
Coddy logo textTech

Trait Sınırlandırıcı Sözdizimi

Coddy'nin Rust Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 40 / 61.

Şimdiye kadar trait'leri tanımlamayı ve bunları struct'lar için uygulamayı öğrendin. Ayrıca esnek kod yazmak için generic'lerle de çalıştın. Şimdi bu kavramları birleştirmenin zamanı: bir generic fonksiyonun hangi türleri kabul edebileceğini sınırlamak için trait'leri kullanmak.

Parametresi üzerinde belirli bir yöntemi çağırması gereken genel bir işlev düşünün. Herhangi bir kısıtlama olmadığında Rust, T türünün bu yönteme sahip olduğuna dair hiçbir güvence vermez:

fn print_info<T>(item: T) {
    println!("{}", item.summarize());  // Hata! T'nin summarize() metodu olmayabilir
}

Çözüm bir trait kısıtlamasıdır. Genel parametrenin sonuna : TraitName ekleyerek Rust'a T'nin bu trait'i uygulaması gerektiğini söylersin:

trait Summary {
    fn summarize(&self) -> String;
}

fn print_info<T: Summary>(item: T) {
    println!("{}", item.summarize());  // Artık Rust bu metodun var olduğunu biliyor
}

<T: Summary> söz dizimi, "T, Summary'yi uygulayan herhangi bir türdür." şeklinde okunur. Artık işlev yalnızca gerekli davranışa sahip türleri kabul eder. Summary uygulamayan bir türü aktarmaya çalışırsanız derleyici bunu açık bir hatayla reddeder.

Bu desen güçlüdür çünkü belirli işlevlere hâlâ erişebilen genel kod yazmanıza olanak tanır. İşleviniz esnek kalır; herhangi bir türle çalışır, ancak yalnızca ihtiyaç duyduğunuz davranışı sağlayan türlerle.

challenge icon

Görev

Kolay

Yalnızca düzgün biçimlendirilmiş mesajların gönderilebilmesini sağlamak için trait sınırlarını kullanan bir bildirim sistemi oluşturalım! Belirli bir trait'i uygulayan herhangi bir türü kabul eden genel bir işlev oluşturacak ve trait sınırlarının genel parametreleri nasıl kısıtladığını göstereceksin.

Kodunu iki dosyaya ayıracaksın:

  • notification.rs: Bir Notify adlı yönteme sahip, message alan ve &self döndüren herkese açık bir String trait'i tanımla. Ardından bu trait'i uygulayan iki herkese açık yapı oluştur:
    • Email: herkese açık bir subject alanına (String) sahip. message yöntemi Email: {subject} döndürmelidir
    • SMS: herkese açık bir content alanına (String) sahip. message yöntemi SMS: {content} döndürmelidir
    Son olarak, send_notification trait'ini uygulayan herhangi bir T türünü kabul eden, Notify adlı herkese açık bir genel işlev oluştur. Bu işlev, öğe üzerinde message() çağrısının sonucunu yazdırmalıdır.
  • main.rs: Bildirim modülünü dahil et ve sağlanan girdileri kullanarak hem bir Email hem de bir SMS örneği oluştur. Genel işlevinin send_notification uygulayan herhangi bir türle çalıştığını göstermek için her biriyle Notify çağrısı yap.

Buradaki temel fikir, send_notification işlevinin aldığı somut türü bilmemesidir. Yalnızca türün bir mesaj üretebildiğini bilir. T: Notify trait sınırı bu yeteneği garanti eder.

Çıktında her iki bildirimin de gönderildiği gösterilmelidir:

Email: {subject}
SMS: {content}

Örneğin, Meeting Tomorrow ve On my way! girdileriyle:

Email: Meeting Tomorrow
SMS: On my way!

İki girdi alacaksın: e-posta konusu ve SMS içeriği.

Kendin dene

mod notification;

use notification::{Email, SMS, send_notification};

fn main() {
    // Girdileri oku
    let mut subject = String::new();
    std::io::stdin().read_line(&mut subject).expect("Failed to read line");
    let subject = subject.trim().to_string();
    
    let mut content = String::new();
    std::io::stdin().read_line(&mut content).expect("Failed to read line");
    let content = content.trim().to_string();
    
    // TODO: subject ile bir Email örneği oluştur
    
    // TODO: content ile bir SMS örneği oluştur
    
    // TODO: email ile send_notification'ı çağır
    
    // TODO: sms ile send_notification'ı çağır
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Rust derleyicisi