Option Enum'ına Yeniden Bakış
Coddy'nin Rust Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 17 / 61.
Rust'ta Option<T> ile zaten karşılaştınız—bu, var olabilecek veya olmayabilecek değerleri temsil etmek için kullanılan standart enum'dur. Şimdi buna bir OOP merceğinden bakalım: Option sadece bir enum değildir; nullable değerleri güvenli ve zarif bir şekilde işlemenizi sağlayan güçlü yerleşik metotlara sahip bir türdür.
Her seferinde eşleştirme yapmak yerine, doğrudan Option değerleri üzerinde metotlar kullanabilirsiniz. unwrap_or metodu, eğer varsa içindeki değeri, yoksa sağladığınız varsayılan bir değeri döndürür:
let maybe_name: Option<String> = Some(String::from("Alice"));
let name = maybe_name.unwrap_or(String::from("Guest"));
println!("{}", name); // Alice
let empty: Option<String> = None;
let fallback = empty.unwrap_or(String::from("Guest"));
println!("{}", fallback); // Guest
map metodu, eğer varsa içindeki değeri dönüştürür ve None değerini değiştirmeden bırakır. Bu, sürekli None kontrolü yapmanıza gerek kalmadan işlemleri zincirleme yapmanıza olanak tanır:
let maybe_num: Option<i32> = Some(5);
let doubled = maybe_num.map(|x| x * 2);
println!("{:?}", doubled); // Some(10)
let nothing: Option<i32> = None;
let still_nothing = nothing.map(|x| x * 2);
println!("{:?}", still_nothing); // None
Bu yöntemler OOP prensiplerini somutlaştırır; Option türü "belki bir değer" kavramını kapsüller ve onunla çalışmak için temiz bir arayüz sağlar. Onu incelemek için harici mantık yazmak yerine nesne üzerindeki metotları çağırırsınız.
Görev
KolayOption metotlarını kullanarak isteğe bağlı verileri zarif bir şekilde işleyen bir kullanıcı profili sistemi oluşturalım. Kullanıcıların bir takma adı (nickname) ayarlanmış olabilir veya olmayabilir; sisteminiz açık bir eşleştirme (matching) yapmadan her iki durumu da şık bir şekilde ele alacaktır.
Kodunuzu düzenlemek için iki dosya oluşturacaksınız:
profile.rs: İki alanı olan genel birProfileyapısı (struct) tanımlayın:username(String) venickname(Option<String>). Şunları uygulayın:- Bir kullanıcı adı ve isteğe bağlı bir takma ad alan bir
newyapıcı metodu (constructor) - Eğer varsa takma adı, yoksa yedek olarak kullanıcı adını döndüren bir
display_namemetodu; bunu yönetmek içinunwrap_orkullanın - Eğer varsa takma adı köşeli parantez içine alınmış (
"[CoolNick]"gibi) birOption<String>olarak döndüren, takma ad yoksaNonedöndüren birformatted_nicknamemetodu; değeri dönüştürmek içinmapkullanın
- Bir kullanıcı adı ve isteğe bağlı bir takma ad alan bir
main.rs: Profil modülünüzü dahil edin ve biri takma adlı, diğeri takma adsız olmak üzere iki profil oluşturun.Optionmetotlarının mevcut ve eksik değerleri nasıl farklı şekilde işlediğini göstermek için her iki profil üzerinde her iki metodu da gösterin.
formatted_nickname metodu bir Option döndürdüğü için, yazdırırken hata ayıklama biçimlendirmesini ({:?}) kullanın.
Çıktınız, her iki profili de gösterecek şekilde tam olarak şu formatı izlemelidir:
Display name: {name}
Formatted nickname: {option}
Display name: {name}
Formatted nickname: {option}Örneğin, kullanıcı adı "alice" ve takma adı "Ace" olan bir profil ile kullanıcı adı "bob" olan ve takma adı olmayan başka bir profil için çıktı şöyle olacaktır:
Display name: Ace
Formatted nickname: Some("[Ace]")
Display name: bob
Formatted nickname: NoneÜç girdi alacaksınız: ilk kullanıcı adı, ilk kullanıcının takma adı ve ikinci kullanıcı adı (takma adı olmayan).
Kopya kağıdı
Option<T> türü, açıkça eşleştirme (matching) yapmadan isteğe bağlı değerlerle çalışmak için yöntemler sağlar.
unwrap_or yöntemi, eğer varsa içindeki değeri, yoksa (None ise) varsayılan bir değeri döndürür:
let maybe_name: Option<String> = Some(String::from("Alice"));
let name = maybe_name.unwrap_or(String::from("Guest"));
println!("{}", name); // Alice
let empty: Option<String> = None;
let fallback = empty.unwrap_or(String::from("Guest"));
println!("{}", fallback); // Guest
map yöntemi, eğer varsa içindeki değeri dönüştürür, None değerini ise değiştirmeden bırakır:
let maybe_num: Option<i32> = Some(5);
let doubled = maybe_num.map(|x| x * 2);
println!("{:?}", doubled); // Some(10)
let nothing: Option<i32> = None;
let still_nothing = nothing.map(|x| x * 2);
println!("{:?}", still_nothing); // None
Bu yöntemler, sürekli None kontrolü yapmaya gerek kalmadan Option değerleri üzerinde işlemleri zincirlemeye olanak tanır.
Kendin dene
mod profile;
use profile::Profile;
fn main() {
// Girdileri oku
let mut input1 = String::new();
std::io::stdin().read_line(&mut input1).expect("Failed to read line");
let username1 = input1.trim().to_string();
let mut input2 = String::new();
std::io::stdin().read_line(&mut input2).expect("Failed to read line");
let nickname1 = input2.trim().to_string();
let mut input3 = String::new();
std::io::stdin().read_line(&mut input3).expect("Failed to read line");
let username2 = input3.trim().to_string();
// TODO: username1 ve nickname1 (Some) ile ilk profili oluştur
// TODO: username2 ve takma ad olmadan (None) ikinci profili oluştur
// TODO: İlk profil için display_name ve formatted_nickname değerlerini yazdır
// Bir Option döndürdüğü için formatted_nickname için {:?} kullanın
// TODO: İkinci profil için display_name ve formatted_nickname değerlerini 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 Player