آموزش Rust-قسمت چهارم(نوع داده ها)

راست یک زبان نوع ایستاست(Statically type language).مفهومش اینه که کامپایلر در زمان اجرای برنامه باید از نوع تمامی متغیرهای استفاده شده در برنامه خبر داشته باشه.بعضی موارد پیش میاد که خود کامپایلر می تونه حدس بزنه که چه نوعی رو برای متغیربر اساس مقداری که بهش دادیم، انتخاب کنه و بعضی مواقع نمی تونه یه مثال:let guess: u32 = &quot42&quot.parse().expect(&quotNot a number!&quot);مثال بالا یک رشته عددی رو با کمک متد ()parse به عدد تبدیل می‌کنه و اون رو در متغیر از نوع اعداد غیرعلامت دار میریزه (جلوتر بیشتر توضیح میدیم).متد ()expect برای جلوگیری از خطاست به این معنا که اگر کاربری به جای عدد مثلا رشته "42w" رو وارد کرد و ()parse نتونست این رشته رو به عدد تبدیل کنه متد ()expect رشته ی "Not a number" رو به عنوان پیغام خطا چاپ می‌کنه.اگر در مثال بالا نوع داده رو مشخص نکینم با خطای زیر رو به رو می‌شیم:error[E0282]: type annotations needed --> src/main.rs:2:9 | 2 | let guess = &quot42&quot.parse().expect(&quotNot a number!&quot); | ^^^^^ | | | cannot infer type for `_` | consider giving `guess` a typeنوع‌های مقیاسینوع مقیاسی نمایش دهنده ی یه مقدار هست.راست از چهار نوع مقیاس متفاوت پشتیبانی می‌کنه.اعداد صحیح(Integer)،اعداد اعشار(floating-point numbers)،بولی(Boolean)،کارکتر(char).اعداد صحیحبازه‌ی اعداد صحیح علامت‌دار از فرمول زیر استفاده میشه:بازه‌اعداد غیرعلامت دار هم :جدول زیر انواع داده صحیح علامت دار و غیر علامت دار رو همراه با مقدار حافظه‌ای که در بر می‌گیرند نمایش میده.به عنوان مثال اگر بخوایم بازه‌ی اعدادی که در نوع i8 در نظر بگیریم از فرمول بالا استفاده می‌کنیم که میشه 127 تا 128- میشه.نوع مقادیری که میشه به انواع جدول بالا داد در جدول زیر هست:حالا از کجا تشخیص بدیم که برای برنامه مون چه نوعی رو انتخاب کنیم؟به صورت پیش فرض i32 توسط کامپایلر انتخاب میشه که بهترین انتخاب هست حتی توی سیستم های 64بیتی.سرریز اعداد صحیح(Integer Overflow) فرض کنید از u8 برای برنامه مون استفاده کنیم بازی u8 از 0 تا 255 هست خب اگر من برنامه نویس به اشتباه عدد 256 رو وارد کنم چی اتفاقی میفته؟اگر توی حالت Debug Mode باشه کامپایلر در هنگام اجرا اخطار میده (Panic).اگر در حالت Release Mode باشه Rust پیغام خطای نمایش نمیده و به جاش عدد 256 رو به مکمل دو تبدیل میکنه که میشه 0 و اگر 257 بزنیم مکمل دو میشه 1. اعداد اعشاریدو نوع f32 و f64 هست که به صورت پیش فرض اگر در عدد اعشار وارد شده نوع رو مشخص نکینم Rust f64 رو انتخاب می‌کنه که خود راست دلیل این کار رو به دلیل سرعت بالا در cpu های مدرن می‌دونه مثال:fn main() { let x = 2.0; // f64 let y: f32 = 3.0; // f32 }عملگرهای عددیشامل جمع،تفریق،ضرب و تقسیم هست:fn main() { // addition let sum = 5 + 10; // subtraction let difference = 95.5 - 4.3; // multiplication let product = 4 * 30; // division let quotient = 56.7 / 32.2; // remainder let remainder = 43 % 5; }نوع بولیمثل زبان های برنامه نویسی دیگه دارای دو مقدار false و true داره.fn main() { let t = true; let f: bool = false; // with explicit type annotation }نوع کاراکتریحروف در Rust با استفاده از ' Single Qution جدا میشن.fn main() { let c = 'z'; let z = 'ℤ'; let heart_eyed_cat = '?'; }انواع مرکب تاپلتاپل ها یکی از راه های گروه بندی کردن انواع مختلف هست.تاپل ها دارای طول یکسان هستند به این معنا که زمانی که یک تاپل رو ساختید دیگه نمی‌تونید طولش رو افزایش یا کاهش بدین.برای ساخت تاپل باید از اعداد رو با کاما در داخل پرانتز از هم جدا کنید و هر عدد می‌تونه نوع متفاوتی داشته باشهfn main() { let tup: (i32, f64, u8) = (500, 6.4, 1); }برای خواندن مقادیر از تاپل از دو روش میشه استفاده کرد که با مثال نمایش دادم:fn main() { let tup = (500, 6.4, 1); let (x, y, z) = tup; println!(&quotThe value of y is: {}&quot, y); }در مثال بالا یه تاپل بدون در نظر گرفتن نوع‌ها ایجاد کردیم و حالا هر مقدار رو به در خط دوم به یک متغیر نسبت دادیم و وقتی y رو چاپ کنیم مقدار 6.4 چاپ میشه.روش دوم: فراخوانی مستقیم مقدارها با استفاده از .let x: (i32, f64, u8) = (500, 6.4, 1); let five_hundred = x.0; let six_point_four = x.1; let one = x.2;اگر با زبان‌های برنامه نویسی دیگه آشنا باشید معمولا اون ها هم مثل Rust اندیس‌هاشون از 0 شروع میشه.نوع مرکب آرایهراه دیگه برای گروه‌بندی کردن مقادیر استفاده از آرایه هاست،فرقش با تاپل اینه که مثل تاپل نمی‌تونید انواع مختلفی رو در یه آرایه کنار هم قرار بدین به معنای دیگه اگر در یک آرایه عدد عنصر اول عدد بود باید تا آخرین عنصر عدد باشه یا اگر یک عنصر رشته بود باید عناصر دیگه هم رشته باشه و به جای پرانتز از براکت استفاده می کنه.fn main() { let a = [1, 2, 3, 4, 5]; }به گفته خود سایت Rust، آرایه ها زمانی خیلی مفید هستند که می‌خوایم تقسیم حافظه در Stack به جای Heap باشه که در این مورد توی آموزش های بعدی صحبت می‌کنیم.یه مثال دیگه برای رشته‌ها.let months = [&quotJanuary&quot, &quotFebruary&quot, &quotMarch&quot, &quotApril&quot, &quotMay&quot, &quotJune&quot, &quotJuly&quot,&quotAugust&quot, &quotSeptember&quot, &quotOctober&quot, &quotNovember&quot, &quotDecember&quot];برای آرایه ها می‌تونیم تعداد و نوع مشخص کنیم.let a: [i32; 5] = [1, 2, 3, 4, 5];اگر می خواید یه آرایه درست کنید که دارای پنج آرایه باشه و هر پنج آرایه دارای مقدار 3 باشنlet a = [3, 3, 3, 3, 3];راه دومlet a = [3; 5];خواندن اعداد از آرایه‌هاfn main() { let a = [1, 2, 3, 4, 5]; let first = a[0]; let second = a[1]; }اگر اندیس آرایه‌ای رو اشتباه وارد کنید با خطا مواجه میشینfn main() { let a = [1, 2, 3, 4, 5]; let index = 10; let element = a[index]; println!(&quotThe value of element is: {}&quot, element); }آرایه ی مثال بالا دارای پنج عنصر هست اما ما عنصر 10 رو درخواست کردیم و برنامه در هنگام اجرا خطای زیر رو نمایش میده:$ cargo run Compiling arrays v0.1.0 (file:///projects/arrays) Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs Running `target/debug/arrays` thread 'main' panicked at 'index out of bounds: the len is 5 but the index is 10', src/main.rs:5:19 note: Run with `RUST_BACKTRACE=1` for a backtrace.خب این آموزش هم تموم شد توی آموزش بعدی درباره‌ی فانکشن ها صحبت می‌کنیم. https://virgool.io/@komeilshahmoradi/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-rust-%D9%82%D8%B3%D9%85%D8%AA-%D9%BE%D9%86%D8%AC%D9%85%D8%AA%D9%88%D8%A7%D8%A8%D8%B9-yfbfbeugvbwt