CLI
- Rust kursu
- Orta seviye
- Ders 111/115
- 6 dk
clap ile list ve get alt komutları yaparsın.
CLI
Son adımda sorguları komut satırına bağlıyoruz. Gerçek projede clap alt komutlarıyla:
#[derive(Subcommand)]
enum Komut {
Liste,
Etiket { ad: String },
Yazar { ad: String },
}Alıştırmada aynı yapıyı dilim kalıplarıyla kuruyoruz. Her komut bir süzgece dönüşür; böylece listeleme kodu tek yerde kalır:
let suzgec: Box<dyn Fn(&Yazi) -> bool> = match args {
["liste"] => Box::new(|_| true),
["etiket", e] => Box::new(move |y| y.etiketler.iter().any(|x| x == e)),
["yazar", a] => Box::new(move |y| y.yazar == *a),
[k, ..] => return Err(format!("bilinmeyen komut: {k}")),
[] => return Err(String::from("komut gerekli")),
};Çalıştırıcı
Süzgeç hazır olunca listeleme her komut için aynıdır. Komut işleme Result<Vec<String>, String> döndürür; main yalnızca yazdırır:
fn calistir(v: &[Yazi], args: &[&str]) -> Result<Vec<String>, String> {
let suzgec = /* yukarıdaki match */;
Ok(v.iter()
.filter(|y| y.yayinda && suzgec(y))
.map(|y| format!("{}. {}", y.id, y.konu))
.collect())
}Uygulama Blog CLI
veri_seti() verisi ile yukarıdaki calistir fonksiyonunu yaz. ["etiket", "web"], ["yazar", "ece"] ve ["sil"] komutlarını sırayla çalıştır; sonuç satırlarını, hatada hata: MESAJ yazdır.
Başlangıç kodu
#[derive(Debug, Clone)]
struct Yazi {
id: u32,
konu: String,
yazar: String,
etiketler: Vec<String>,
yayinda: bool,
}
fn veri_seti() -> Vec<Yazi> {
let y = |id, konu: &str, yazar: &str, et: &[&str], yayinda| Yazi {
id,
konu: konu.to_string(),
yazar: yazar.to_string(),
etiketler: et.iter().map(|e| e.to_string()).collect(),
yayinda,
};
vec![
y(1, "Rust ile başlangıç", "ece", &["rust", "giriş"], true),
y(2, "Sahiplik", "can", &["rust"], false),
y(3, "Web sunucusu", "ece", &["rust", "web"], true),
y(4, "Python notları", "ali", &["python"], true),
]
}
fn main() {
// buraya yaz
}Örnek çözüm
#[derive(Debug, Clone)]
struct Yazi {
id: u32,
konu: String,
yazar: String,
etiketler: Vec<String>,
yayinda: bool,
}
fn veri_seti() -> Vec<Yazi> {
let y = |id, konu: &str, yazar: &str, et: &[&str], yayinda| Yazi {
id,
konu: konu.to_string(),
yazar: yazar.to_string(),
etiketler: et.iter().map(|e| e.to_string()).collect(),
yayinda,
};
vec![
y(1, "Rust ile başlangıç", "ece", &["rust", "giriş"], true),
y(2, "Sahiplik", "can", &["rust"], false),
y(3, "Web sunucusu", "ece", &["rust", "web"], true),
y(4, "Python notları", "ali", &["python"], true),
]
}
fn calistir(v: &[Yazi], args: &[&str]) -> Result<Vec<String>, String> {
let suzgec: Box<dyn Fn(&Yazi) -> bool> = match args {
["liste"] => Box::new(|_| true),
["etiket", e] => {
let e = e.to_string();
Box::new(move |y| y.etiketler.iter().any(|x| *x == e))
}
["yazar", a] => {
let a = a.to_string();
Box::new(move |y| y.yazar == a)
}
[k, ..] => return Err(format!("bilinmeyen komut: {k}")),
[] => return Err(String::from("komut gerekli")),
};
Ok(v.iter()
.filter(|y| y.yayinda && suzgec(y))
.map(|y| format!("{}. {}", y.id, y.konu))
.collect())
}
fn main() {
let yazilar = veri_seti();
let komutlar: [&[&str]; 3] = [&["etiket", "web"], &["yazar", "ece"], &["sil"]];
for k in komutlar {
match calistir(&yazilar, k) {
Ok(sonuclar) => {
for s in sonuclar {
println!("{}", s);
}
}
Err(e) => println!("hata: {}", e),
}
}
}Beklenen çıktı
3. Web sunucusu 1. Rust ile başlangıç 3. Web sunucusu hata: bilinmeyen komut: sil
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Süzgeçleri neden <code>Box<dyn Fn></code> içinde tutuyoruz?
- Her match kolu farklı türde bir closure üretir; ortak tür gerekir Doğru cevap
- Daha hızlıdır
- Closure'lar Box olmadan çağrılamaz
- Gerekli değil
Açıklama: Her closure eşsiz bir türdür; bir match ifadesinin tüm kolları aynı türü döndürmelidir.
2 Ortak süzgeç türü
let suzgec: Box<dyn ____(&Yazi) -> bool> = Box::new(|_| true);
let suzgec: Box<dyn Fn(&Yazi) -> bool> = Box::new(|_| true);
Açıklama: Birden çok kez çağrılan, yalnızca okuyan closure Fn'dir.
3 Komut ve sonuç
| Kavram | Anlamı |
|---|---|
etiket web |
3. Web sunucusu |
yazar ali |
4. Python notları |
liste |
1, 3, 4 |
sil |
hata: bilinmeyen komut |