Trait Vektörleri
Coddy'nin Rust Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 46 / 61.
Box<dyn Trait> kullanarak tek bir değişkenin farklı türleri tutabilmesini gördün. Asıl güç, bunu koleksiyonlarla birleştirdiğinde ortaya çıkar: tek bir vektörde birden fazla farklı türü depolamak.
Normal bir vektör, tüm öğelerin aynı türde olmasını gerektirir. Kedileri de içeren bir Vec<Dog> oluşturamazsınız. Ancak trait nesneleriyle, ortak bir trait’i uygulayan her şeyi barındıran bir vektör oluşturabilirsiniz:
trait Speak {
fn speak(&self) -> String;
}
struct Dog;
struct Cat;
struct Bird;
impl Speak for Dog {
fn speak(&self) -> String { String::from("Woof!") }
}
impl Speak for Cat {
fn speak(&self) -> String { String::from("Meow!") }
}
impl Speak for Bird {
fn speak(&self) -> String { String::from("Tweet!") }
}
fn main() {
let animals: Vec<Box<dyn Speak>> = vec![
Box::new(Dog),
Box::new(Cat),
Box::new(Bird),
];
}
Vec<Box<dyn Speak>> türü, "kutulanmış özellik nesnelerinden oluşan bir vektör" anlamına gelir. Her element, Speak özelliğini uygulayan bir şeye işaret eden bir Box'tır: gerçek türler farklı olabilir. Her değeri vektöre eklerken Box::new() ile sarmalarsın.
Bu kalıp; UI bileşenleri, oyun varlıkları veya eklenti sistemleri gibi birbiriyle ilişkili ancak farklı nesne koleksiyonlarını yönetmeniz gereken esnek sistemler oluşturmak için gereklidir.
Görev
KolayFarklı uyarı türlerini işleyebilen bir bildirim sistemi oluşturalım! Çeşitli bildirim türlerini, e-postaları, SMS mesajlarını ve anlık bildirimleri, hepsini trait nesnelerini kullanarak tek bir vektörde depolayan bir koleksiyon oluşturacaksınız.
Kodunuzu iki dosyaya ayıracaksınız:
notifications.rs:Notifyalan ve gönderilen bildirimi açıklayan birsenddöndüren&selfmetoduna sahip herkese açık birStringtrait'i tanımlayın. Ardından üç herkese açık struct oluşturun:Email: herkese açık birrecipientalanına (String) sahip.sendmetoduEmail to: {recipient}döndürmelidir.Sms: herkese açık birphonealanına (String) sahip.sendmetoduSMS to: {phone}döndürmelidir.Push: herkese açık birdevicealanına (String) sahip.sendmetoduPush to: {device}döndürmelidir.
main.rs: Bildirimler modülünü dahil edin ve üç bildirim türünün tamamını barındıranVec<Box<dyn Notify>>türünde bir vektör oluşturun. Sağlanan girdileri kullanarak her bildirim türünden bir tane oluşturun, bunları vektörünüze sırayla (Email, Sms, Push) ekleyin, ardından vektörün ilk öğesindesend()çağrısının sonucunu yazdırın.
Buradaki temel kavram, Email, Sms ve Push tamamen farklı struct'lar olmasına rağmen, Notify trait'ini paylaştıkları için aynı vektörde birlikte bulunabilmeleridir. Her öğe, trait nesnesi oluşturmak için Box::new() ile sarmalanır.
Çıktınız ilk bildirimi göstermelidir:
Email to: {recipient}Örneğin, alice@example.com, 555-1234 ve iPhone-12 girdileriyle:
Email to: alice@example.comÜç girdi alacaksınız: e-posta alıcısı, telefon numarası ve cihaz adı.
Kendin dene
mod notifications;
use notifications::{Notify, Email, Sms, Push};
fn main() {
// Girdileri oku
let mut recipient = String::new();
std::io::stdin().read_line(&mut recipient).expect("Failed to read line");
let recipient = recipient.trim().to_string();
let mut phone = String::new();
std::io::stdin().read_line(&mut phone).expect("Failed to read line");
let phone = phone.trim().to_string();
let mut device = String::new();
std::io::stdin().read_line(&mut device).expect("Failed to read line");
let device = device.trim().to_string();
// TODO: Farklı bildirim türlerini tutmak için bir Vec<Box<dyn Notify>> oluştur
// TODO: Girdileri kullanarak Email, Sms ve Push örnekleri oluştur
// TODO: Bunları sırayla (Email, Sms, Push) vektöre Box::new() kullanarak ekle
// TODO: İlk eleman üzerinde send() çağrısının sonucunu yazdır
}
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
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 Player9Trait Nesneleri
Dinamik GönderimTrait VektörleriTrait Nesneleri Üzerinde YinelemeÖzet - Hayvanat Bahçesi YöneticisiKendi başına pratik yap: Online Rust derleyicisi