Where Cümleciği
Coddy'nin Rust Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 42 / 61.
Daha fazla trait sınırı ekledikçe, fonksiyon imzalarını okumak zorlaşabilir. Her biri birkaç trait gerektiren birden fazla jenerik parametreye sahip bir fonksiyonu düşünün:
fn complex_operation<T: Display + Clone, U: Debug + Summary>(first: T, second: U) {
// ...
}
Bu çalışır, ancak imza kalabalıklaşıyor. where yan cümlesi, trait sınırlarını parametre listesinden sonraya taşıyarak daha temiz bir alternatif sunar:
fn complex_operation<T, U>(first: T, second: U)
where
T: Display + Clone,
U: Debug + Summary,
{
// ...
}
Her iki sürüm de işlevsel olarak aynıdır—where yan tümcesi tamamen okunabilirlik ile ilgilidir. Her bir türün gereksinimleri kendi satırında görünür, bu da her bir genel parametrenin neye ihtiyaç duyduğunu taramayı kolaylaştırır.
where yan tümcesi, sınırlar karmaşık olduğunda veya çok sayıda generic parametreniz olduğunda özellikle değerli hale gelir. Kısıtlamaların aşağıda ayrı ayrı listelenmesiyle, fonksiyon adının ve parametrelerin bir bakışta görünür kalmasını sağlar. Sınırlar basit bir T: Trait ifadesinin ötesine geçtiğinde, çoğu Rust kod tabanında tercih edilen stil budur.
Görev
KolayKarmaşık trait sınırlarını okunabilir tutmak için where ifadesini kullanan bir veri işleme sistemi oluşturalım! Her biri farklı trait'ler gerektiren birden fazla tip parametresine sahip genel (generic) bir fonksiyon oluşturacak ve sınırları where sözdizimini kullanarak temiz bir şekilde düzenleyeceksiniz.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
processor.rs: İki genel trait ve her ikisini de kullanan genel bir fonksiyon tanımlayın:Summarize—&selfalan ve birStringdöndürensummarymetoduna sahip bir trait.Validate—&selfalan ve birbooldöndürenvalidatemetoduna sahip bir trait.
process_itemsadında genel bir fonksiyon oluşturun. İlk tipin hemClonehem deSummarizetrait'lerini uygulaması gerektiğini, ikinci tipin iseValidatetrait'ini uygulaması gerektiğini belirtmek için birwhereifadesi kullanın. Fonksiyon, ilk öğenin özetini yazdırmalı, ardından ikinci öğenin geçerli olup olmadığını yazdırmalıdır.main.rs: Gerekli trait'leri uygulayan iki genel struct oluşturun:Article— genel birtitlealanına (String) sahip.Summarizetrait'iniArticle: {title}döndürecek şekilde uygulayın veClonetüretin (derive).Form— genel birfilledalanına (bool) sahip.Validatetrait'inifilleddeğerini döndürecek şekilde uygulayın.
process_itemsfonksiyonunu çağırın.
where ifadesi, tüm sınırları açılı ayraçlara sıkıştırmaktan çok daha temiz bir fonksiyon imzası oluşturmanızı sağlar. Her tipin gereksinimleri kendi satırında görünür, bu da her bir genel parametrenin neye ihtiyaç duyduğunu görmeyi kolaylaştırır.
Çıktınız, özeti ve ardından doğrulama sonucunu göstermelidir:
Article: {title}
Valid: {true/false}Örneğin, Rust Tips ve true girdileriyle:
Article: Rust Tips
Valid: trueVe Breaking News ve false girdileriyle:
Article: Breaking News
Valid: falseİki girdi alacaksınız: makale başlığı ve formun doldurulup doldurulmadığı (bool olarak ayrıştırın).
Kopya kağıdı
where ifadesi, kısıtlamaları parametre listesinden sonraya taşıyarak, genel (generic) fonksiyonlar için trait sınırlarını belirtmenin daha temiz bir yolunu sunar:
fn complex_operation<T, U>(first: T, second: U)
where
T: Display + Clone,
U: Debug + Summary,
{
// ...
}
Bu, satır içi (inline) trait sınırlarıyla işlevsel olarak aynıdır ancak okunabilirliği artırır:
fn complex_operation<T: Display + Clone, U: Debug + Summary>(first: T, second: U) {
// ...
}
where ifadesi özellikle şu durumlarda yararlıdır:
- Birden fazla genel (generic) parametreniz olduğunda
- Her parametre birkaç trait sınırı gerektirdiğinde
- Fonksiyon imzasını temiz ve taranabilir tutmak istediğinizde
Her türün gereksinimleri kendi satırında görünür, bu da her bir genel parametrenin neye ihtiyaç duyduğunu görmeyi kolaylaştırır. Sınırlar basit bir T: Trait ifadesinin ötesine geçtiğinde, çoğu Rust kod tabanında tercih edilen stil budur.
Kendin dene
mod processor;
use processor::{Summarize, Validate, process_items};
use std::io;
// TODO: Genel bir title alanı (String) olan genel bir Article yapısı tanımlayın
// Article için Clone özelliğini türetin (Derive)
// TODO: Article için Summarize özelliğini uygulayın
// summary metodu "Article: {title}" döndürmelidir
// TODO: Genel bir filled alanı (bool) olan genel bir Form yapısı tanımlayın
// TODO: Form için Validate özelliğini uygulayın
// validate metodu filled değerini döndürmelidir
fn main() {
let mut title = String::new();
io::stdin().read_line(&mut title).expect("Failed to read line");
let title = title.trim().to_string();
let mut filled_input = String::new();
io::stdin().read_line(&mut filled_input).expect("Failed to read line");
let filled: bool = filled_input.trim().parse().expect("Failed to parse bool");
// TODO: Verilen başlık (title) ile bir Article oluşturun
// TODO: Verilen doluluk (filled) değeri ile bir Form oluşturun
// TODO: Article ve Form ile process_items fonksiyonunu çağırın
}
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