Rust
Hata yönetimi
anyhow ile API hatalarını yönetirsin.
Hata yönetimi
Kullanıcının hatalı kaydı düzeltebilmesi için hatanın nerede ve neden olduğunu bilmesi gerekir. Gerçek projede anyhow::Context ile eklenen bağlamı burada bir hata enum'ı ile kuruyoruz:
#[derive(Debug)]
enum KayitHatasi {
AlanSayisi { no: usize, adet: usize },
Id { no: usize, deger: String },
}
impl fmt::Display for KayitHatasi {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
KayitHatasi::AlanSayisi { no, adet } => write!(f, "kayıt {no}: 5 alan beklendi, {adet} geldi"),
KayitHatasi::Id { no, deger } => write!(f, "kayıt {no}: geçersiz id: {deger}"),
}
}
}
Hatayla dönen okuyucu
Bu kez bozuk kaydı atlamak yerine ilk hatada duruyoruz; collect ile Result<Vec<_>, _> toplamak bunu tek satırda yapar:
fn oku(veri: &str) -> Result<Vec<Yazi>, KayitHatasi> {
veri.lines()
.enumerate()
.map(|(i, s)| kayit_coz(i + 1, s))
.collect()
}
Uygulama Hatalı kaydı raporla
Yukarıdaki KayitHatasi (Display ile), kayit_coz(no, s) ve oku fonksiyonlarını yaz. İki geçerli kayıt için N yazı, x|a|b|c|true için hatayı yazdır.
Örnek çözümü göster
use std::fmt;
#[derive(Debug, Clone)]
struct Yazi {
id: u32,
konu: String,
yazar: String,
etiketler: Vec<String>,
yayinda: bool,
}
#[derive(Debug)]
enum KayitHatasi {
AlanSayisi { no: usize, adet: usize },
Id { no: usize, deger: String },
}
impl fmt::Display for KayitHatasi {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
KayitHatasi::AlanSayisi { no, adet } => write!(f, "kayıt {no}: 5 alan beklendi, {adet} geldi"),
KayitHatasi::Id { no, deger } => write!(f, "kayıt {no}: geçersiz id: {deger}"),
}
}
}
fn kayit_coz(no: usize, s: &str) -> Result<Yazi, KayitHatasi> {
let alanlar: Vec<&str> = s.split('|').collect();
let [id, konu, yazar, etiket, yayinda] = alanlar[..] else {
return Err(KayitHatasi::AlanSayisi { no, adet: alanlar.len() });
};
Ok(Yazi {
id: id.parse().map_err(|_| KayitHatasi::Id { no, deger: id.to_string() })?,
konu: konu.to_string(),
yazar: yazar.to_string(),
etiketler: etiket.split(',').map(String::from).collect(),
yayinda: yayinda == "true",
})
}
fn oku(veri: &str) -> Result<Vec<Yazi>, KayitHatasi> {
veri.lines().enumerate().map(|(i, s)| kayit_coz(i + 1, s)).collect()
}
fn main() {
match oku("1|Rust ile başlangıç|ece|rust|true\n2|Sahiplik|can|rust|false") {
Ok(v) => println!("{} yazı", v.len()),
Err(e) => println!("{}", e),
}
match oku("x|a|b|c|true") {
Ok(v) => println!("{} yazı", v.len()),
Err(e) => println!("{}", e),
}
}
Kendini test et
-
Kayıt numarasını hataya eklemek için en uygun yer neresi?
- Display uygulamasında
- Hiçbir yerde
- Satırları enumerate ile dolaşan okuma döngüsünde
- main içinde
Cevabı göster
Satırları enumerate ile dolaşan okuma döngüsünde — Numarayı yalnızca döngü bilir; bu yüzden hatayı oluşturan fonksiyona numara parametre olarak verilir.
-
Numaralı dolaşma
veri.lines()
.____()
.map(|(i, s)| kayit_coz(i + 1, s))
.collect()
Cevabı göster
veri.lines()
.enumerate()
.map(|(i, s)| kayit_coz(i + 1, s))
.collect()
-
Kayıt ve hata
- x|a|b|c|true
- geçersiz id: x
- 1|a|b
- 5 alan beklendi, 3 geldi
- (geçerli)
- Ok
- İlk hata
- Okuma durur
Sıradaki ders: Kayıt listeleme