Trait Vektörleri
Coddy'nin Rust Journey'sinin Object Oriented Programming 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ördeki tüm öğelerin aynı türde olması gerekir. İçinde kediler de bulunan bir Vec<Dog> oluşturamazsınız. Ancak trait nesneleriyle, ortak bir trait'i uygulayan herhangi bir şeyi tutan 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 push bildirimlerini tek bir vektörde trait nesnelerini kullanarak depolayan bir koleksiyon oluşturacaksın.
Kodunu iki dosyaya ayıracaksın:
notifications.rs:&selfalan ve gönderilmekte olan bildirimi açıklayan birStringdöndüren birNotifytrait'i ilesendmethodunu tanımla. Ardından üç public struct oluştur:Email: public birrecipientalanına (String) sahip.send,Email to: {recipient}döndürmeliSms: public birphonealanına (String) sahip.send,SMS to: {phone}döndürmeliPush: public birdevicealanına (String) sahip.send,Push to: {device}döndürmeli
main.rs: notifications modülünü içe aktar ve üç bildirim türünün tamamını tutanVec<Box<dyn Notify>>türünde bir vektör oluştur. Sağlanan inputs değerlerini kullanarak her bildirim türünden bir tane oluştur, bunları vektörüne sırayla (Email, Sms, Push) ekle, ardından vektörün ilk öğesi üzerindesend()çağrısının result değerini yazdır.
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 element, trait nesnesi oluşturmak için Box::new() ile sarılır.
Çıktın ilk bildirimi göstermeli:
Email to: {recipient}Örneğin alice@example.com, 555-1234 ve iPhone-12 inputs değerleriyle:
Email to: alice@example.comÜç input alacaksın: e-posta recipient'ı, telefon numarası ve device 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.
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 Player9Trait Nesneleri
Dinamik GönderimTrait VektörleriTrait Nesneleri Üzerinde YinelemeÖzet - Hayvanat Bahçesi YöneticisiKendi başına pratik yap: Online Rust derleyicisi