Rust
Trait ile arama
Searchable trait'i ile arama özelliği eklersin.
Trait ile arama
Rafın arama yapabilmesi için içindeki öğelerin bir sorguyla eşleşip eşleşmediğini söyleyebilmesi gerekir. Bunu bir trait ile ifade edip arama metodunu yalnızca bu trait'i uygulayan öğeler için sunarız:
pub trait Aranabilir {
fn eslesir(&self, sorgu: &str) -> bool;
}
impl<T: Aranabilir> Raf<T> {
pub fn ara(&self, sorgu: &str) -> Vec<&T> {
self.ogeler.iter().filter(|x| x.eslesir(sorgu)).collect()
}
}
Raf<u32> hâlâ geçerlidir ama ara metodu yoktur; çünkü u32 Aranabilir değildir.
Kitap için uygulama
Kitap, adında ya da yazarında sorgu geçiyorsa eşleşsin. Büyük/küçük harf farkını yok saymak için iki taraf da küçültülür:
impl Aranabilir for Kitap {
fn eslesir(&self, sorgu: &str) -> bool {
let s = sorgu.to_lowercase();
self.ad.to_lowercase().contains(&s)
|| self.yazar.to_lowercase().contains(&s)
}
}
Trait aynı modülde olduğu için Kitap'ın gizli alanlarına erişebilir.
Uygulama Rafta ara
Önceki Kitap ve Raf ile Aranabilir trait'ini ve ara metodunu yaz. Rafa Tutunamayanlar (Oğuz Atay, 1972), Tehlikeli Oyunlar (Oğuz Atay, 1973) ve Kürk Mantolu Madonna (Sabahattin Ali, 1943) ekle. ara("atay") sonucunu 2: Tutunamayanlar, Tehlikeli Oyunlar biçiminde yazdır.
Örnek çözümü göster
mod kitaplik {
pub struct Kitap {
ad: String,
yazar: String,
yil: u16,
}
impl Kitap {
pub fn new(ad: &str, yazar: &str, yil: u16) -> Self {
Self {
ad: ad.to_string(),
yazar: yazar.to_string(),
yil,
}
}
pub fn ad(&self) -> &str {
&self.ad
}
pub fn yil(&self) -> u16 {
self.yil
}
}
pub struct Raf<T> {
ogeler: Vec<T>,
}
impl<T> Raf<T> {
pub fn new() -> Self {
Self { ogeler: Vec::new() }
}
pub fn ekle(&mut self, x: T) {
self.ogeler.push(x);
}
pub fn len(&self) -> usize {
self.ogeler.len()
}
}
pub trait Aranabilir {
fn eslesir(&self, sorgu: &str) -> bool;
}
impl Aranabilir for Kitap {
fn eslesir(&self, sorgu: &str) -> bool {
let s = sorgu.to_lowercase();
self.ad.to_lowercase().contains(&s) || self.yazar.to_lowercase().contains(&s)
}
}
impl<T: Aranabilir> Raf<T> {
pub fn ara(&self, sorgu: &str) -> Vec<&T> {
self.ogeler.iter().filter(|x| x.eslesir(sorgu)).collect()
}
}
}
use kitaplik::{Kitap, Raf};
fn main() {
let mut raf = Raf::new();
raf.ekle(Kitap::new("Tutunamayanlar", "Oğuz Atay", 1972));
raf.ekle(Kitap::new("Tehlikeli Oyunlar", "Oğuz Atay", 1973));
raf.ekle(Kitap::new("Kürk Mantolu Madonna", "Sabahattin Ali", 1943));
let bulunan = raf.ara("atay");
let adlar: Vec<&str> = bulunan.iter().map(|k| k.ad()).collect();
println!("{}: {}", bulunan.len(), adlar.join(", "));
}
Kendini test et
-
<code>ara</code> neden <code>Vec<T></code> değil <code>Vec<&T></code> döndürüyor?
- Öğeleri raftan taşımadan ya da kopyalamadan göstermek için
- &T daha hızlı yazdırılır
- Vec<T> generic olamaz
- Fark yok
Cevabı göster
Öğeleri raftan taşımadan ya da kopyalamadan göstermek için — &self ile ödünç alınan raftan öğe taşınamaz; referans döndürmek kopyalamaktan da ucuzdur.
-
Sınırlı arama
impl<T: ____> Raf<T> {
pub fn ara(&self, sorgu: &str) -> Vec<&T> {
self.ogeler.iter().filter(|x| x.eslesir(sorgu)).collect()
}
}
Cevabı göster
impl<T: Aranabilir> Raf<T> {
pub fn ara(&self, sorgu: &str) -> Vec<&T> {
self.ogeler.iter().filter(|x| x.eslesir(sorgu)).collect()
}
}
-
Sorgu ve eşleşen kitaplar
- "atay"
- Tutunamayanlar, Tehlikeli Oyunlar
- "MADONNA"
- Kürk Mantolu Madonna
- "sabahattin"
- Yalnızca Ali'nin kitabı
- "xyz"
- Boş vektör
Sıradaki ders: Test altyapısı