انواع خطاهای Dynamic

گاهی اوقات می‌خواهیم اجازه دهیم هر نوع خطای بدون نوشتن enum خودمان که تمام احتمالات مختلف را پوشش می‌دهد، برگردانده شود. ویژگی std::error::Error ایجاد یک object مشخ استه که می‌تواند حاوی هر خطایی باشد را آسان می‌کند.

use std::error::Error;
use std::fs;
use std::io::Read;

fn read_count(path: &str) -> Result<i32, Box<dyn Error>> {
    let mut count_str = String::new();
    fs::File::open(path)?.read_to_string(&mut count_str)?;
    let count: i32 = count_str.parse()?;
    Ok(count)
}

fn main() {
    fs::write("count.dat", "1i3").unwrap();
    match read_count("count.dat") {
        Ok(count) => println!("تعداد: {count}"),
        Err(err) => println!("Error: {err}"),
    }
}
This slide should take about 5 minutes.

تابع read_countمی‌تواند std::io::Error (از عملیات فایل) یا std::num::ParseIntError (از String::parse) را برگرداند.

خطاهای Boxing باعث صرفه‌جویی در کد می شود، اما توانایی رسیدگی به موارد خطای مختلف را به طور متفاوت در برنامه از بین می‌برد. به این ترتیب استفاده از Box<dyn Error> در public API یک کتابخانه ایده خوبی نیست، اما می‌تواند گزینه خوبی در برنامه‌ای باشد که فقط می‌خواهید پیام خطا را در جایی نمایش دهید.

هنگام تعریف یک نوع خطای سفارشی، مطمئن شوید که ویژگی std::error::Error را اجرا کنید تا بتوان آن را در جعبه قرار داد. اما اگر نیاز به پشتیبانی از ویژگی no_std دارید، به خاطر داشته باشید که ویژگی std::error::Error در حال حاضر با no_std در nightly سازگار است.