Result türünün kullanımı, Rust'taki hata işleme için en önemli yaklaşımlardan biri haline gelmiştir. Tarihsel olarak birçok dilde—örneğin, C—hatalar genellikle özel dönüş değerleri veya küresel değişkenlerle bildirilmiş, bu da bu sinyallerin göz ardı edilmesi sırasında sık sık hatalara yol açmıştır. Rust, Result<T, E> enum'u aracılığıyla hata türlerinin açıkça tanımlandığı bir yola gitmiş, bu da hataların kazara göz ardı edilmesini imkansız hale getirmiştir — derleyici, her iki dalı (başarı ve başarısızlık) işlemeyi zorunlu kılar.
Sorun: Hata işlemenin maksimum güvenli ve okunabilir olmasını sağlamak, "gizli" hataları ortadan kaldırmak ve istisnalar kullanmadan kodun güvenilirliğini artırmak gerekiyordu.
Çözüm: Result<T, E>, başarı durumunda Ok(T) ve hata durumunda Err(E) olan iki seçeneği olan bir enum'dur. Bu, hataların açıkça işlenmesini zorunlu kılar, ya da hataları unwrap ile açıkça göz ardı eder veya panik bekleriz. Ayrıca, ? operatörü, hata iletiminde yaygın olan kalıpları özlü hale getirir.
Kod örneği:
use std::fs::File; use std::io::{self, Read}; fn read_file(path: &str) -> Result<String, io::Error> { let mut file = File::open(path)?; let mut contents = String::new(); file.read_to_string(&mut contents)?; Ok(contents) }
Ana özellikler:
? operatörü aracılığıyla basitlik.? operatörünü hatayı yukarı iletmek için her zaman kullanabilir miyiz?
Hayır, yalnızca fonksiyonun hata türü, ?'nin sağındaki ifadenin türü ile uyuşuyorsa. Türler uyumsuzsa, hata türünü .map_err() yöntemiyle veya kendi türünüzle açıkça dönüştürmeniz gerekir.
Kod örneği:
fn f() -> Result<(), String> { let _f = File::open("foo").map_err(|e| e.to_string())?; Ok(()) }
Sonucu kullanmamayı tercih edebilir miyiz, eğer hatalarla ilgilenmiyorsak?
Hayır, eğer Result türündeki sonuç işlenmezse derleyici uyarı veya hata verecektir. Ya .unwrap() çağırarak, ya da açıkça .ok()/ .err()/ let _ = ... veya hatayı doğru şekilde kaydederek çağırmalısınız.
Eğer hata içeren bir Result üzerinde .unwrap() çağırılırsa ne olur?
Panik tetiklenecek! ve programın yürütülmesi duracaktır, bu genellikle acil bir kapanmaya yol açar. Bu nedenle unwrap() yalnızca başarı garantili olduğunda kullanılabilir.
let _ = ...;) ve kaydetmedenBir geliştirici, bir dosyadan yapılandırma okumaya karar verdi ve okuma sonucunda unwrap() kullandı.
Artılar:
Eksiler:
Yapılandırma okunurken hatalar kaydedilir ve Result + ? operatörü ile çağrı yığınına geri döner.
Artılar:
Eksiler: