Rust, hataların açık bir şekilde yönetimi üzerine kuruludur: istisnalar yoktur, bunun yerine Result<T, E> döndürülen bir değer kullanılır. Bu, kodun güvenliğini ve öngörülebilirliğini sağlar.
Konu geçmişi:
Birçok dil istisnalar üzerinde ilerledi, bu da beklenmedik durumlara ve çalışma zamanında istisnaları açıkça işlemeye ihtiyaç duyulmasına yol açtı. Rust, başından beri türler aracılığıyla kontrolü tercih etti, tüm hatalar bir fonksiyonun imzasının parçası olmalıdır.
Sorun:
Ana görev, hataların yok sayılmadığı ve maskelemek yerine açıkça belirtildiği, "çöken" fonksiyonların olmadığı ama kodun yine de kompakt ve okunabilir olduğu bir kod yazmaktır. Hataları yukarı doğru doğru bir şekilde iletmek, tür hakkında bilgi kaybetmemek ve mantığı karıştırmamak gereklidir.
Çözüm:
Ana araç Result<T, E> tipi ve ? operatörüdür, bu otomatik olarak sonucu "çözer": hata durumunda, fonksiyondan hemen çıkış yapılır ve hata geri döner, başarı durumunda ise değer geri döner.
Kod örneği:
fn read_number(file: &str) -> Result<i32, std::io::Error> { let content = std::fs::read_to_string(file)?; let num: i32 = content.trim().parse()?; Ok(num) }
Anahtar özellikler:
.map_err() ve diğer yöntemler aracılığıyla)Unit (void) döndüren fonksiyonlarda ? kullanmak mümkün mü?
Hayır, ? operatörü yalnızca Result veya Option döndüren fonksiyonlar içinde geçerlidir. Eğer bir fonksiyon () döndürüyorsa, ? kullanılamaz.
? ile yapılan birkaç çağrıda hata türleri farklı olursa ne olur?
Bir derleme hatası meydana gelir: hata türü açıkça tanımlanmalıdır. Tüm hataları tek bir türde birleştirmek için .map_err() kullanılmalı veya thiserror kullanılmalı ya da API seviyesinde bir enum sarmalayıcı tanımlanmalıdır. Örnek:
fn foo() -> Result<_, MyError> { let a = bar()?; let b = baz().map_err(MyError::Baz)?; Ok(…) }
İç mantıkta .unwrap() ne kadar tehlikeli?
"Ana" kodda unwrap() kullanılabileceği konusunda yaygın bir yanlış anlama vardır, "kesinlikle çökmez". Gerçekte, görünmeyen küçük bir hata bile çalışma zamanında bir panik ile sonuçlanır — bu da programın güvenliğini tehlikeye atar.
unwrap/expect ile yakalanması, özellikle iç mantıktaÜretim kodunda hızlı hata ayıklama sonrası birçok unwrap() bırakılmış. Sonuç olarak, uygulama kullanıcıdan gelen hatalı giriş nedeniyle herhangi bir ayrıştırma hatasında çöküyordu.
Artıları:
Eksileri:
Tüm hataların açık bir şekilde tanımlandığı ve yalnızca ? ve .map_err() kullanarak tüm hata bilgilerini koruduğu Result<T, E> yığını kullanıldı.
Artıları:
Eksileri: