CodeBlanks Logo Icon CodeBlanks

Result ile komut

Komutları Result döndüren fonksiyonlara bölersin.

Result ile komut

Komut işleyici her komutun sonucunu Result<String, String> olarak döndürsün: başarıda kullanıcıya gösterilecek mesaj, hatada açıklama. Dilim kalıpları argümanları doğrudan eşlemeyi sağlar:

fn calistir(d: &mut Defter, args: &[&str]) -> Result<String, String> {
    match args {
        ["ekle", metin @ ..] if !metin.is_empty() => {
            d.ekle(metin.join(" "));
            Ok(String::from("eklendi"))
        }
        ["sil", n] => { /* n'yi parse et */ }
        [k, ..] => Err(format!("bilinmeyen komut: {k}")),
        [] => Err(String::from("komut yok")),
    }
}

Silme ve doğrulama

Silme komutu numarayı çevirmeli ve aralıkta olduğunu denetlemelidir. ? yerine map_err ile anlaşılır mesajlar üretilir:

["sil", n] => {
    let i: usize = n.parse().map_err(|_| format!("geçersiz numara: {n}"))?;
    if i == 0 || i > d.notlar.len() {
        return Err(format!("böyle bir not yok: {i}"));
    }
    let silinen = d.notlar.remove(i - 1);
    Ok(format!("silindi: {silinen}"))
}

Uygulama Komut işleyici

fn calistir(d: &mut Defter, args: &[&str]) -> Result<String, String> yaz: ekle, sil ve bilinmeyen komutları yukarıdaki gibi ele al. ["ekle", "süt", "al"], ["sil", "x"] ve ["uç"] sonuçlarını {:?} ile ayrı satırlara yazdır.

Başlangıç kodu

main.rs
struct Defter {
    notlar: Vec<String>,
}

impl Defter {
    fn new() -> Self {
        Self { notlar: Vec::new() }
    }
    fn ekle(&mut self, metin: String) {
        self.notlar.push(metin);
    }
}

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
struct Defter {
    notlar: Vec<String>,
}

impl Defter {
    fn new() -> Self {
        Self { notlar: Vec::new() }
    }
    fn ekle(&mut self, metin: String) {
        self.notlar.push(metin);
    }
}

fn calistir(d: &mut Defter, args: &[&str]) -> Result<String, String> {
    match args {
        ["ekle", metin @ ..] if !metin.is_empty() => {
            d.ekle(metin.join(" "));
            Ok(String::from("eklendi"))
        }
        ["sil", n] => {
            let i: usize = n.parse().map_err(|_| format!("geçersiz numara: {n}"))?;
            if i == 0 || i > d.notlar.len() {
                return Err(format!("böyle bir not yok: {i}"));
            }
            let silinen = d.notlar.remove(i - 1);
            Ok(format!("silindi: {silinen}"))
        }
        [k, ..] => Err(format!("bilinmeyen komut: {k}")),
        [] => Err(String::from("komut yok")),
    }
}

fn main() {
    let mut d = Defter::new();
    println!("{:?}", calistir(&mut d, &["ekle", "süt", "al"]));
    println!("{:?}", calistir(&mut d, &["sil", "x"]));
    println!("{:?}", calistir(&mut d, &["uç"]));
}

Beklenen çıktı

Ok("eklendi")
Err("geçersiz numara: x")
Err("bilinmeyen komut: uç")

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 <code>["ekle", metin @ ..]</code> kalıbında <code>metin</code> nedir?

  • Eleman sayısı
  • "ekle"den sonraki tüm elemanların dilimi Doğru cevap
  • Yalnızca ikinci eleman
  • Son eleman

Açıklama: .. kalan elemanları eşler; metin @ ile bu kısım bir dilim olarak bağlanır.

2 Kalanı bağla

Soru
match args {
    ["ekle", metin @ ____] => Ok(metin.join(" ")),
    _ => Err(String::from("?")),
}
Cevap
match args {
    ["ekle", metin @ ..] => Ok(metin.join(" ")),
    _ => Err(String::from("?")),
}

Açıklama: Dilim kalıbında .. kalan elemanların tamamını eşler.

3 Argümanlar ve sonuç

Kavram Anlamı
["ekle", "süt", "al"] Ok("eklendi")
["sil", "x"] Err("geçersiz numara: x")
["uç"] Err("bilinmeyen komut: uç")
[] Err("komut yok")

Orta seviye bölümündeki tüm dersler