عملگرد Try

خطاهای زمان اجرا مانند connection-refused یا file-not-found با نوع «نتیجه» مدیریت می‌شوند، اما تطبیق این نوع در هر تماس می‌تواند دشوار باشد. اپراتور ? برای برگرداندن خطاها به تماس گیرنده استفاده می‌شود. این به شما امکان می‌دهد تا موارد مشترک را بازگردانید.

match some_expression {
    Ok(value) => value,
    Err(err) => return Err(err),
}

بسیار ساده‌تر

some_expression?

می‌توانیم از این برای ساده‌سازی کد رسیدگی به خطا استفاده کنیم:

use std::io::Read;
use std::{fs, io};

fn read_username(path: &str) -> Result<String, io::Error> {
    let username_file_result = fs::File::open(path);
    let mut username_file = match username_file_result {
        Ok(file) => file,
        Err(err) => return Err(err),
    };

    let mut username = String::new();
    match username_file.read_to_string(&mut username) {
        Ok(_) => Ok(username),
        Err(err) => Err(err),
    }
}

fn main() {
    //fs::write("config.dat", "alice").unwrap();
    let username = read_username("config.dat");
    println!("نام‌کاربری یا خطا: {username:?}");
}
This slide should take about 5 minutes.

تابع read_username را برای استفاده از ? ساده کنید.

نکات کلیدی:

  • متغیرusername می تواند Ok(string) یا Err(error) باشد.
  • از فراخوانی fs::write برای آزمایش سناریوهای مختلف استفاده کنید: بدون فایل، فایل خالی، فایل با نام کاربری.
  • توجه داشته باشید که main تا زمانی که std::process::Termination را پیاده‌سازی کند، می‌تواند نتیجه<(), E> را برگرداند. در عمل، این بدان معنی است که E پیاده‌سازی Debug را انجام‌می‌دهد. فایل اجرایی، نوع Err را چاپ می‌کند و در صورت خطا، وضعیت خروج غیر صفر (nonzero) را برمی‌گرداند.