بیش از یک راه برای رسیدگی به خطاها در Rust وجود دارد، بنابراین مطمئن شوید که همه گزینهها را در نظر گرفتهاید.
خطاها اجتناب ناپذیر هستند و می توانند به دلایل مختلفی رخ دهند، از ورودی نامعتبر کاربر گرفته تا خرابی شبکه، نقص سخت افزاری یا اشکالات برنامه نویسی. مدیریت خطا فرآیند شناسایی، گزارش و بازیابی چنین خطاهایی برای جلوگیری از خرابی برنامه یا خرابی داده ها است.
مدیریت موثر خطا در Rust بسیار مهم است. این به شما امکان می دهد برنامه های کاربردی قوی و قابل اعتمادی ایجاد کنید که می توانند خطاها و خرابی های غیرمنتظره را مدیریت کنند. مکانیسمهای رسیدگی به خطا Rust به شما امکان میدهد برنامههای انعطافپذیر و امنی را توسعه دهید که نگهداری آنها آسانتر است.
انواع خطاها در زنگ زدگی
Rust دارای یک سیستم نوع غنی است که می توانید از آن برای رسیدگی ماهرانه خطاها، با توجه به انواع آنها استفاده کنید. مزایای سیستم غنی از نوع خطای Rust نسبت به رویکردهای سنتی رسیدگی به خطا را نمی توان دست کم گرفت. سیستم نوع خطا، ایمنی نوع، ترکیب پذیری، بیان و اشکال زدایی را بهبود می بخشد.
در اینجا لیستی از انواع خطاهای رایج در Rust آمده است:
- نوع std::io::Error نشان دهنده خطاهای ورودی/خروجی مانند یافت نشدن فایل، رد شدن مجوز، یا رسیدن به انتهای فایل است.
- نوع std::num::ParseIntError خطاهایی را نشان می دهد که در عملیات تجزیه رشته به عدد صحیح رخ می دهد.
- نوع std::option::NoneError خطاهای ناشی از باز کردن گزینه های خالی را نشان می دهد.
- نوع std::result::Result
یک نوع Result عمومی است که میتوانید برای نمایش هرگونه خطا از آن استفاده کنید.
هر نوع خطا مجموعه ای از روش ها و ویژگی های خاص خود را برای رسیدگی به آن به روش های خاص دارد.
در اینجا نمونه ای از مدیریت خطا در Rust برای عملیات خواندن فایل آورده شده است:
use std::fs::File;
use std::io::Read;
fn read_file(path: &str) -> Result<String, std::io::Error> {
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}
تابع read_file محتویات فایل را در مسیر مشخص شده می خواند و آن را به صورت رشته برمی گرداند. اگر عملیات باز کردن یا خواندن فایل با شکست مواجه شود، یک std::io:: خطا را برمیگرداند. ? عملگر خطا را منتشر می کند و خطا را به عنوان یک نتیجه برمی گرداند.
مکانیسم های رسیدگی به خطا در زنگ زدگی
یکی از ویژگیهای کلیدی که به ایمنی Rust کمک میکند، مکانیسمهای کنترل خطا است. چهار مکانیسم اصلی رسیدگی به خطا در Rust وجود دارد: نوع Result، نوع Option، Panic! ماکرو و صفت خطا.
انواع Result و Option امکان مدیریت ساختار یافته خطا را فراهم می کنند. می توانید از وحشت استفاده کنید! ماکرو برای رسیدگی به خطاهای غیرقابل جبران. ویژگی Error به شما امکان می دهد انواع خطای سفارشی و مدیریت خطای سفارشی را تعریف کنید.
نوع نتیجه
نوع Result یک نوع داخلی است که نشان دهنده نتیجه عملیاتی است که ممکن است شکست بخورد. دارای دو نوع است: نوع Ok که نشان دهنده موفقیت و حاوی یک مقدار است و Err که نشان دهنده شکست و حاوی مقدار خطا است.
در اینجا نحوه استفاده از نوع Result برای باز کردن یک فایل و خواندن محتوای آن آمده است:
use std::fs::File;
use std::io::prelude::*;
fn read_file(file_path: &str) -> Result<String, std::io::Error> {
let mut file = File::open(file_path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}
fn main() {
let result = read_file("file.txt");
match result {
Ok(contents) => println!("{}", contents),
Err(e) => println!("Error: {}", e),
}
}
تابع read_file در مسیر فایل قرار می گیرد و یک خطای Result
نوع گزینه
نوع Option یک نوع داخلی است که حضور یا عدم حضور یک مقدار را نشان می دهد. نوع Option دو نوع دارد. برخی نشان دهنده یک مقدار و None نشان دهنده عدم وجود یک مقدار است.
در اینجا نحوه استفاده از نوع Option برای بازیابی اولین عنصر یک برداری آمده است.
fn get_first_element<T: Clone>(vec: Vec<T>) -> Option<T> {
if vec.is_empty() {
None
} else {
Some(vec.first().unwrap().clone())
}
}
fn main() {
let vec = vec![1, 2, 3];
let result = get_first_element(vec);
match result {
Some(element) => println!("{}", element),
None => println!("The vector is empty."),
}
}
تابع get_first_element یک نوع Option
وحشت! ماکرو
وحشت! ماکرو عملکردی را برای رسیدگی به خطاهای غیرقابل جبران در Rust فراهم می کند. در تماس با وحشت! ماکرو، پیغام خطا را چاپ می کند و برنامه را خاتمه می دهد.
در اینجا نمونه ای از استفاده از پانیک وجود دارد! ماکرو برای نشان دادن اینکه یک تابع دارای آرگومان های نامعتبر است.
fn divide(dividend: f64, divisor: f64) -> f64 {
if divisor == 0.0 {
panic!("The divisor cannot be zero.");
}
dividend / divisor
}
fn main() {
let result = divide(4.0, 0.0);
println!("{}", result);
}
تابع تقسیم بررسی می کند که آیا مقسوم علیه صفر است یا خیر. اگر مقسوم علیه صفر باشد، تابع پانیک را فراخوانی می کند! ماکرو با پیام خطا؛ در غیر این صورت تابع محاسبه و نتیجه را برمی گرداند
تابع اصلی تابع تقسیم را با آرگومان های نامعتبر فراخوانی می کند تا وحشت ایجاد شود! کلان.
این پیام خطا است:
صفت خطا
صفت خطا یک ویژگی داخلی است که رفتار انواع خطا را تعریف می کند. صفت خطا عملکردی را برای تعریف انواع خطای سفارشی و مدیریت خطای سفارشی ارائه می دهد.
در اینجا نمونه ای از تعریف یک نوع خطای سفارشی است که نشان دهنده خطای یافت نشدن فایل است.
use std::error::Error;
use std::fmt;
use std::io::Read;
#[derive(Debug)]
struct FileNotFound(String);
impl fmt::Display for FileNotFound {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "File not found: {}", self.0)
}
}
impl Error for FileNotFound {}
fn read_file(file_path: &str) -> Result<String, Box<dyn Error>> {
let mut file = std::fs::File::open(file_path).map_err(|e| FileNotFound(format!("{}", e)))?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}
fn main() {
let result = read_file("file.txt");
match result {
Ok(contents) => println!("{}", contents),
Err(e) => println!("Error: {}", e),
}
}
نوع خطای سفارشی ساختار FileNotFound است. نوع شامل یک مسیر فایل است و نوع FileNotFound ویژگی Display را برای بازگرداندن پیامهای خطای کاربرپسند و صفت Error را برای نشان دادن اینکه این یک نوع خطا است پیادهسازی میکند.
در تابع read_file، نوع خطای FileNotFound نشان دهنده خطای file not found است و روش map_err std::io::Error را به خطای FileNotFound تبدیل می کند. در نهایت، نوع Box
تابع اصلی تابع read_file را با مسیر فایل فراخوانی می کند و در صورت یافتن فایل، محتوای آن را در کنسول چاپ می کند. در غیر این صورت پیغام خطا را چاپ می کند.
در اینجا نتیجه برای فایلی که وجود ندارد آمده است:
برای ایمنی برنامه می توانید از مدل مالکیت Rust استفاده کنید
به همراه مکانیزم مدیریت خطای باشکوه Rust، Rust همچنین از مدل مالکیتی استفاده میکند که به اطمینان از ایمنی برنامههای شما در حافظه کمک میکند.
Rust در زمان کامپایل، قبل از اجرای برنامه، قوانین مالکیت را با یک بررسی کننده قرض تضمین می کند.