Veri İçeren Enum'lar
Coddy'nin Rust Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 14 / 61.
Rust'taki temel enum'lar, Direction::North veya Status::Active gibi sabit bir varyant kümesine sahip bir tür tanımlamanıza olanak tanır. Ancak Rust enum'ları bundan çok daha güçlüdür. Her bir varyant kendi verisini taşıyabilir, bu da enum'ları gerçek dünya senaryolarını modellemek için inanılmaz derecede esnek hale getirir.
Farklı mesaj türlerinin farklı bilgiler taşıdığı bir mesajlaşma sistemi düşünün. Bir metin mesajının içeriği vardır, bir hareket komutunun koordinatları vardır ve bir çıkış sinyalinin ise hiçbir şeyi yoktur. Rust'ta, tüm bunları tek bir enum ile temsil edebilirsiniz:
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(u8, u8, u8),
}
Her varyantın farklı bir şekli vardır. Quit veri tutmaz; sadece bir sinyaldir.
Move, isimlendirilmiş alanlara sahip struct benzeri bir sözdizimi kullanır. Write, demet (tuple) sözdizimini kullanarak tek bir String tutar. ChangeColor, RGB bileşenlerini temsil eden üç değer tutar.
Bu varyantların örneklerini oluşturmak şu şekilde görünür:
let m1 = Message::Quit;
let m2 = Message::Move { x: 10, y: 20 };
let m3 = Message::Write(String::from("Hello"));
let m4 = Message::ChangeColor(255, 128, 0);
Bu yaklaşımın güzelliği, m1, m2, m3 ve m4 değerlerinin tamamının aynı türde olmasıdır: Message. Onları aynı koleksiyonda saklayabilir, aynı fonksiyona geçirebilir veya tek bir fonksiyondan herhangi bir varyantı döndürebilirsiniz. Enum, farklı veri şekillerini tek bir tür altında birleştirirken her bir varyantın ihtiyaç duyduğu özel bilgileri korur.
Görev
KolayFarklı uyarı türlerini temsil etmek için veri içeren enum'ları kullanan bir bildirim sistemi oluşturalım. Her bildirim türü farklı bilgiler taşır; bazılarında mesajlar, bazılarında sayısal değerler bulunur ve bazıları ise basit sinyallerdir.
Kodunuzu düzenlemek için iki dosya oluşturacaksınız:
notification.rs: Üç varyantı olan genel birNotificationenum'ı tanımlayın:Alert— tek birStringmesajı tutar (tuple sözdizimi)Reminder— isimlendirilmiş alanlar tutar:title(String) veminutes(u32)Dismiss— veri tutmaz, sadece bir sinyaldir
main.rs: Bildirim modülünüzü dahil edin ve her varyanttan birer örnek oluşturun. Ardından, her üç varyantın da aynı türde olduğunu ancak farklı veriler taşıdığını göstermek için her bildirim hakkındaki bilgileri yazdırın.
Yazdırırken, her bildirimi görüntülemek için hata ayıklama biçimlendirmesini ({:?}) kullanın. Bu şekilde yazdırılabilmesi için enum'ınızda Debug trait'ini türetmeniz (derive) gerekecektir.
Çıktınız, her biri kendi satırında olmak üzere üç bildirimi de göstermelidir:
Alert("{message}")
Reminder { title: "{title}", minutes: {minutes} }
DismissÖrneğin, "Server down" uyarı mesajı, "Meeting" başlıklı ve 30 dakikalık bir hatırlatıcı ile çıktı şu şekilde olacaktır:
Alert("Server down")
Reminder { title: "Meeting", minutes: 30 }
DismissÜç girdi alacaksınız: uyarı mesajı, hatırlatıcı başlığı ve hatırlatıcı dakikası.
Kopya kağıdı
Rust'taki enum varyantları farklı veri türlerini taşıyabilir, bu da onları tek bir tür altında çeşitli senaryoları modellemek için güçlü kılar.
Veri İçeren Enum'ları Tanımlama
Her varyant kendi veri yapısına sahip olabilir:
enum Message {
Quit, // Veri yok
Move { x: i32, y: i32 }, // İsimlendirilmiş alanlar (struct benzeri)
Write(String), // Tek değer (tuple sözdizimi)
ChangeColor(u8, u8, u8), // Birden fazla değer (tuple sözdizimi)
}
Enum Örnekleri Oluşturma
let m1 = Message::Quit;
let m2 = Message::Move { x: 10, y: 20 };
let m3 = Message::Write(String::from("Hello"));
let m4 = Message::ChangeColor(255, 128, 0);
Farklı veriler taşımalarına rağmen tüm örnekler aynı türdedir (Message); bu da onların koleksiyonlarda saklanmasına, fonksiyonlara aktarılmasına veya fonksiyonlardan tek tip bir şekilde döndürülmesine olanak tanır.
Debug Trait'i
Enum'ları {:?} biçimlendirmesini kullanarak yazdırmak için Debug trait'ini türetin:
#[derive(Debug)]
enum Message {
// varyantlar...
}
Kendin dene
mod notification;
use notification::Notification;
fn main() {
// Girdileri oku
let mut alert_message = String::new();
std::io::stdin().read_line(&mut alert_message).expect("Failed to read line");
let alert_message = alert_message.trim().to_string();
let mut reminder_title = String::new();
std::io::stdin().read_line(&mut reminder_title).expect("Failed to read line");
let reminder_title = reminder_title.trim().to_string();
let mut minutes_input = String::new();
std::io::stdin().read_line(&mut minutes_input).expect("Failed to read line");
let reminder_minutes: u32 = minutes_input.trim().parse().expect("Failed to parse minutes");
// TODO: alert_message kullanarak bir Alert bildirimi oluşturun
// TODO: reminder_title ve reminder_minutes kullanarak bir Reminder bildirimi oluşturun
// TODO: Bir Dismiss bildirimi oluşturun
// TODO: Her bir bildirimi hata ayıklama (debug) biçimlendirmesi {:?} kullanarak yazdırın
// Her bildirim kendi satırına yazdırılmalıdı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 Player