Modül dersleri (2/2)
Hata İşleme ve ? Operatör
Rust'un felsefesi, hata olasılığını açıkça tanımanızı ve kodunuzu, program derlenmeden önce bunları ele alacak şekilde yapılandırmanızı teşvik eder.
Rust'taki hatalar iki ana kategoriye ayrılır: kurtarılamaz hatalar (panic! makrosu aracılığıyla anında sonlandırılmaya neden olur) ve kurtarılabilir hatalar (Result<T, E> türü kullanılarak yönetilir).
Sonuç<T, E> Tür ve Desen Eşleştirmesi
Kurtarılabilir hataların çoğu, şu şekilde tanımlanan bir numaralandırma olan Result<T, E> türünü döndürür:
enum Result<T, E> {
Ok(T),
Err(E),
}Sonucu incelemek için kalıp eşleştirmeyi kullanabiliriz:
use std::fs::File;
fn main() {
let greeting_file_result = File::open("hello.txt");
let greeting_file = match greeting_file_result {
Ok(file) => file,
Err(error) => panic!("Problem opening the file: {:?}", error),
};
}? Operatörüyle Hata Yayılımı
Bir işlevi uygularken, hatayı doğrudan onun içinde ele almak yerine, çoğu zaman hatayı çağırana geri göndermek isteriz, böylece ne yapacaklarına karar verebilirler. Bu işleme hata yayılımı adı verilir.
Rust, hataları yaymak için sözdizimsel bir kısayol olarak ? operatörünü sağlar. Bir Result değeri Ok ise, Ok'nin iç değeri ifade tarafından döndürülür; Err ise, sanki bir return Err(...) kullanmışız gibi mevcut fonksiyonun tamamından Err hatası döndürülür.
use std::fs::File;
use std::io::{self, Read};
fn read_username_from_file() -> Result<String, io::Error> {
let mut username_file = File::open("username.txt")?;
let mut username = String::new();
username_file.read_to_string(&mut username)?;
Ok(username)
}[!ÖNEMLİ]
?operatörü yalnızca uygulandığı değerle uyumlu bir tür döndüren işlevlerde kullanılabilir (genellikleResult,OptionveyaFromResidualuygulayan türler).
Özel Hatalar
Hatanın insanlar tarafından okunabilir bir temsilini sağlamak için std::fmt::Display özelliğini (ve isteğe bağlı olarak std::error::Error) uygulayarak kendi özel hata türlerimizi tanımlayabiliriz:
use std::fmt;
#[derive(Debug)]
struct MyError {
details: String,
}
impl fmt::Display for MyError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Error: {}", self.details)
}
}
impl std::error::Error for MyError {}Kendin dene
Alıştırma 1: ? ile bir dosyayı okumak operatör
Read_username_from_file işlevini, ? Dosyayı açarak ve içeriğini kullanıcı adı dizesine okuyarak oluşturulan hataları yaymak için operatör.
İpucu göster
Hataları yaymak için 'File::open(...)' ve 'username_file.read_to_string(...)' sonrasında '?' karakterini ekleyin.
3 denemeden sonra çözüm mevcut
Alıştırma 2: Bir Sayıyı Ayrıştırma ve İkiye Katlama
&str dize başvurusunu kabul eden ve Result<i32, std::num::ParseIntError> döndüren parse_and_double adında bir işlev yazın. İşlev dizeyi val.parse::<i32>() kullanarak ? ayrıştırma hatalarını yaymak ve başarı durumunda Tamam'a sarılmış iki katına çıkan değeri döndürmek için.
İpucu göster
Dizeyi ayrıştırmak ve hatayı yaymak için `val.parse::<i32>()?`kullanın ve ardından`Ok(num \* 2)` değerini döndürün.
3 denemeden sonra çözüm mevcut
Alıştırma 3: Özel Bir Hata Tanımlama
CustomError adında boş bir yapı tanımlayın. fmt yönteminde hata mesajı olarak 'Si e verificato un errore kişiselleştirilmiş' yazarak bunun için std::fmt::Display özelliğini uygulayın.
İpucu göster
'struct CustomError;' değerini bildirin ve 'fmt' yönteminin içine 'write!(f, "Si e doğrulanmış bir hata kişiselleştirildi")'yazarak Display'i uygulayın.
3 denemeden sonra çözüm mevcut