درک enums و تطبیق الگو در Rust اساسی است. تکنیک های موثر برای اجرای هر دوی آنها را بررسی کنید.
Rust انواع داده های مختلفی را برای انجام عملیات فراهم می کند، از انواع داده های پایه مانند رشته ها، اعداد صحیح و اعداد ممیز شناور گرفته تا انواع داده های ترکیبی مانند بردارها و آرایه ها تا انواع داده های ترکیبی مانند ساختارها و شمارش ها.
Enums (enumerations) یک نوع داده است که امکان نمایش مجموعه ای ثابت از مقادیر، مانند روزهای هفته و رنگ رنگین کمان را فراهم می کند. Enum ها زمانی مفید هستند که مقادیر ممکن برای یک متغیر محدود و شناخته شده باشند.
تعریف Enums در Rust
اعلان enums در Rust مشابه اعلان enums در سی شارپ است. شما از کلمه کلیدی enum به دنبال نام و مجموعه ای از بریس های فرفری برای تعریف شمارش ها استفاده خواهید کرد. شما می توانید انواع (موجودات) ممکن را در پرانتزهای فرفری با کاما به عنوان جداکننده تعریف کنید.
در اینجا یک شماره برای روزهای هفته آمده است:
enum Weekday {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday,
}
شماره روز هفته نشان دهنده روزهای هفته است. انواع نام های روز هستند و هیچ مقدار مرتبطی ندارند. همچنین، انواع enum شما می تواند هر نوع داده Rust باشد.
شما می توانید با تعیین نام نوع با استفاده از عملگر جداکننده مسیر (::) در enum به انواع مختلف دسترسی داشته باشید.
let day = Weekday::Monday;
// statically typed version of the `day` variable
let day: Weekday = Weekday::Monday;
کد مشخص می کند که می خواهید به نوع دوشنبه از شماره روز هفته دسترسی داشته باشید.
انواع و تمایزهای Enums
انواع یک enum با مقادیر صحیح به نام تفکیک مرتبط هستند. بهطور پیشفرض، مقادیر تفکیککننده از صفر شروع میشوند و برای انواع بعدی با 1 افزایش مییابند. با این حال، این امکان وجود دارد که مقادیر متمایز سفارشی را برای هر گونه مشخص کنید.
در اینجا نمونه ای از شماره روز هفته با انواع ارزش اختصاص داده شده است.
enum Weekday {
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6,
Sunday = 7,
}
شماره روز هفته دارای هفت نوع است که هر روز هفته را نشان می دهد، و هر روز دارای یک مقدار (به نام تفکیک کننده) است که به آنها اختصاص داده شده است. انواع به ترتیب روز اول تا آخر هفته هستند.
می توانید با استفاده از نام متغیر به مقدار متمایز دسترسی پیدا کنید.
fn main() {
println!("Monday: {}", Weekday::Monday as i32);
println!("Tuesday: {}", Weekday::Tuesday as i32);
println!("Wednesday: {}", Weekday::Wednesday as i32);
println!("Thursday: {}", Weekday::Thursday as i32);
println!("Friday: {}", Weekday::Friday as i32);
println!("Saturday: {}", Weekday::Saturday as i32);
println!("Sunday: {}", Weekday::Sunday as i32);
}
println! ماکرو برای چاپ تفکیک کننده ها استفاده می شود. هر println! فراخوانی ماکرو دو آرگومان می گیرد: یک رشته قالب و یک مقدار. رشته فرمت نحوه فرمت کردن خروجی را مشخص می کند. مقدار مقدار واقعی است که چاپ می شود.
در این مورد، رشته قالب یک رشته تحت اللفظی است که حاوی نام روز هفته است، و مقدار آن نوع enum با ارسال صریح به نوع عدد صحیح i32 است.
ریختن صریح به i32 ضروری است زیرا Rust enum ها به صورت اعداد صحیح نشان داده می شوند، اما نوع عدد صحیح خاص به اندازه enum بستگی دارد. بهطور پیشفرض، Rust کوچکترین نوع عدد صحیحی را که میتواند همه متمایزکنندههای موجود در enum را نشان دهد، اختصاص میدهد. اما در این مورد، شما می خواهید مقادیر را به صورت اعداد صحیح i32 چاپ کنید، بنابراین باید آنها را به صراحت ارسال کنید.
در اینجا نتیجه اجرای تابع اصلی است:
الگوهای تطبیق در زنگ
تطبیق الگو یک ساختار کنترل Rust است که برای شناسایی الگوهای داده مفید است. تطبیق الگو، نوشتن کد مختصر و کارآمد را در حین کار با ساختارهای داده پیشرفته یا انجام عملیات پیچیده امکان پذیر می کند.
شما از کلمه کلیدی match و سپس جداکننده => برای الگو و عملیات برای الگو به ترتیب استفاده خواهید کرد. این الگو می تواند هر عبارت Rust، از جمله literals، متغیرها و فراخوانی تابع باشد.
در اینجا یک نمونه بیانیه تطبیق آمده است:
fn main(){
let x = 5;
match x {
1 => println!("one"),
2 => println!("two"),
3 => println!("three"),
// runs if none of the patterns match
_ => println!("something else"),
}
}
تابع اصلی x را با چندین الگو مطابقت می دهد و سپس مقدار را بر اساس مقدار x چاپ می کند. الگوی زیرخط (_) یک الگوی کارت وحشی است که برای مواردی که به صراحت مورد بررسی قرار نمیگیرند، بهعنوان نشانهای استفاده میشود.
شماره ها و تطبیق الگو
Enums و تطبیق الگو برای بیان و کار با ساختارهای داده پیشرفته به روشی ایمن و کارآمد مفید هستند. می توانید از enums برای تعریف مجموعه ای ثابت از مقادیر و تطبیق الگو برای کار با آن مقادیر استفاده کنید.
در اینجا یک شماره برای رنگ های رنگین کمان آمده است:
enum Rainbow {
Red,
Orange,
Yellow,
Green,
Blue,
Indigo,
Violet,
}
هر یک از انواع Rainbow enum رنگی از رنگین کمان را نشان می دهد. میتوانید از تطبیق الگو با عبارت match برای تطبیق الگوها در برابر نوع مختلف استفاده کنید تا جریان برنامه را بر اساس رنگ رنگین کمان کنترل کنید.
در اینجا تابعی وجود دارد که نوع رنگ را از فهرست رنگین کمان دریافت می کند و پیامی را بر اساس رنگ چاپ می کند.
fn print_color(color: Rainbow) {
match color {
Rainbow::Red => println!("The color is red!"),
Rainbow::Orange => println!("The color is orange!"),
Rainbow::Yellow => println!("The color is yellow!"),
Rainbow::Green => println!("The color is green!"),
Rainbow::Blue => println!("The color is blue!"),
Rainbow::Indigo => println!("The color is indigo!"),
Rainbow::Violet => println!("The color is violet!"),
}
}
fn main() {
let color = Rainbow::Blue;
print_color(color);
}
هنگامی که سعی می کنید کد بالا را اجرا کنید، ممکن است انواع هرگز ساخته نمی شوند یا هشدارهای مشابهی دریافت کنید زیرا سایر گونه ها به غیر از نوع آبی هرگز در این کد ساخته نشده اند. بنابراین، در این مورد، می توانید با خیال راحت از این هشدارها چشم پوشی کنید زیرا عمدی است.
تابع print_color یک پارامتر رنگ از نوع Rainbow enum را می گیرد. عبارت تطابق با رنگ مجموعه ای از رنگ ها که از طریق نام های مختلف قابل دسترسی هستند مطابقت دارد. و در نهایت پیام بر اساس رنگ همسان چاپ می شود.
شما می توانید از تطبیق الگو برای عملیات پیچیده مانند چندین مقدار بازگشتی بر اساس یک شرط استفاده کنید.
fn calculate_wavelength(color: Rainbow) -> u32 {
match color {
Rainbow::Red => 700,
Rainbow::Orange => 590,
Rainbow::Yellow => 570,
Rainbow::Green => 510,
Rainbow::Blue => 475,
Rainbow::Indigo => 445,
Rainbow::Violet => 400,
}
}
تابعcalculat_wavelength یک نوع رنگ از نوع Rainbow enum را به عنوان پارامتر می گیرد و یک عدد صحیح 32 بیتی بدون علامت را برمی گرداند که طول موج رنگی است که با الگوی مطابقت دارد.
Rust همچنین ساختارهایی را برای ایجاد انواع سفارشی فراهم می کند
Enum ها برای تعریف انواع سفارشی برای چندین عملیات مفید هستند، به خصوص در مواردی که فیلدها مشخص و مشخص هستند.
Rust همچنین ساختارهایی را ارائه می دهد که می توانید از آنها برای ایجاد انواع سفارشی با فیلدهای نامگذاری شده استفاده کنید. برخلاف enums، ساختارها به شما اجازه میدهند تا فیلدهایی از انواع مختلف تعریف کنید که میتوانید به صورت جداگانه به آنها دسترسی داشته باشید و آنها را تغییر دهید.