
روز ۵: انواع دادهها در Rust (i۳۲، f۶۴، bool، char، tuple و array)
بعد از آشنایی با متغیرها و مفهوم immutable و mutable، نوبت به یکی از پایهایترین و در عین حال مهمترین مباحث زبان Rust میرسد، یعنی انواع دادهها. Rust یک زبان strongly typed است و این یعنی نوع دادهها نقش بسیار مهمی در ایمنی، کارایی و شفافیت کد دارند. در روز پنجم از سری آموزش «Rust در ۵۰ روز» بهصورت کامل با انواع دادههای پایه در Rust آشنا میشویم و یاد میگیریم هر نوع داده چه کاربردی دارد و چرا Rust تا این حد روی سیستم تایپ خود حساس است.
برخلاف زبانهایی که نوع داده را در زمان اجرا تشخیص میدهند، Rust بسیاری از خطاها را قبل از اجرای برنامه و در زمان کامپایل شناسایی میکند. این ویژگی باعث میشود برنامههای Rust پایدارتر و قابل اعتمادتر باشند. در این مقاله انواع دادههای عددی، منطقی، کاراکتری و ساختارهای ترکیبی مثل tuple و array را بررسی میکنیم و ذهنیت درستی برای استفاده از آنها در پروژههای واقعی به دست میآوریم.
انواع دادههای عددی در Rust
Rust انواع دادههای عددی متنوعی را برای سناریوهای مختلف در اختیار برنامهنویس قرار میدهد. این زبان بین اعداد صحیح و اعشاری تفاوت قائل میشود و برای هرکدام نوع داده مشخصی دارد. اعداد صحیح معمولاً برای شمارش، اندیسها و مقادیر گسسته استفاده میشوند و اعداد اعشاری برای محاسباتی که دقت اعشاری نیاز دارند کاربرد دارند. انتخاب درست نوع داده عددی تأثیر مستقیمی روی performance و مصرف حافظه دارد.
در Rust انواع داده عددی بهصورت صریح تعریف شدهاند، مثل i32 یا u64، که این شفافیت باعث میشود رفتار برنامه کاملاً قابل پیشبینی باشد. کامپایلر Rust به شما کمک میکند تا از overflowهای ناخواسته و خطاهای عددی جلوگیری کنید. این سطح از دقت در سیستم تایپ، یکی از تفاوتهای اصلی Rust با بسیاری از زبانهای سطح بالا محسوب میشود.
نوع داده i32 و اعداد صحیح
i32 پرکاربردترین نوع داده عدد صحیح در Rust است و بهصورت پیشفرض برای اعداد صحیح استفاده میشود. حرف i نشاندهنده signed بودن عدد است، یعنی میتواند مقادیر مثبت و منفی را نگه دارد، و عدد 32 نشاندهنده تعداد بیتهای اختصاص داده شده به آن است. این نوع داده تعادل خوبی بین مصرف حافظه و کارایی ایجاد میکند و برای اکثر سناریوها انتخاب مناسبی است.
Rust همچنین انواع دیگری مثل i8، i16، i64 و i128 را نیز ارائه میدهد که بسته به نیاز پروژه میتوان از آنها استفاده کرد. انتخاب نوع مناسب به عواملی مثل محدوده اعداد، معماری سیستم و حساسیت به performance بستگی دارد. در Rust این انتخابها آگاهانه هستند و شما دقیقاً میدانید هر عدد چه فضایی از حافظه را اشغال میکند.
let count: i32 = 42;
نوع داده f64 و اعداد اعشاری
برای اعداد اعشاری، Rust دو نوع داده اصلی f32 و f64 را ارائه میدهد. f64 بهصورت پیشفرض استفاده میشود، چون دقت بالاتری دارد و در اکثر معماریها performance بهتری ارائه میدهد. این نوع داده برای محاسبات علمی، مالی و هر جایی که دقت اهمیت دارد مناسب است.
اعداد اعشاری در Rust مطابق استاندارد IEEE-754 پیادهسازی شدهاند و رفتار آنها کاملاً مشخص و قابل پیشبینی است. این موضوع باعث میشود در پروژههای حساس، نتایج محاسبات قابل اعتماد باشند. استفاده از f64 در Rust معمولاً انتخاب امنتری نسبت به f32 است، مگر در شرایطی که محدودیت حافظه یا performance خاصی وجود داشته باشد.
let price: f64 = 19.99;
نوع داده bool در Rust
bool سادهترین نوع داده در Rust است و فقط دو مقدار true و false را میپذیرد. این نوع داده معمولاً در شرطها، حلقهها و کنترل جریان برنامه استفاده میشود. Rust اجازه نمیدهد bool با انواع عددی مخلوط شود و این موضوع باعث جلوگیری از بسیاری از خطاهای منطقی میشود.
برخلاف برخی زبانها که مقادیر عددی را بهصورت ضمنی به true یا false تبدیل میکنند، Rust در این مورد بسیار سختگیر است. این سختگیری باعث میشود شرطها شفافتر و خواناتر باشند و رفتار برنامه همیشه مطابق انتظار توسعهدهنده باقی بماند.
let is_active: bool = true;
نوع داده char و تفاوت آن با String
نوع داده char در Rust برای نمایش یک کاراکتر Unicode استفاده میشود و برخلاف تصور بسیاری از برنامهنویسان، فقط محدود به ASCII نیست. هر char در Rust چهار بایت فضا اشغال میکند تا بتواند تمام کاراکترهای Unicode را پشتیبانی کند. این ویژگی Rust را برای کار با زبانهای مختلف و متنهای چندزبانه بسیار مناسب میکند.
مهم است بدانید char با String متفاوت است. char فقط یک کاراکتر را نگه میدارد، در حالی که String مجموعهای از کاراکترهاست. درک این تفاوت در Rust اهمیت زیادی دارد، چون مدیریت رشتهها یکی از بخشهای حساس این زبان محسوب میشود.
let letter: char = 'A';
tuple در Rust و کاربرد آن
tuple یک نوع داده ترکیبی در Rust است که اجازه میدهد چند مقدار با انواع مختلف را در یک متغیر نگهداری کنید. tupleها اندازه ثابتی دارند و نوع هر عنصر آنها از قبل مشخص است. این ساختار برای بازگرداندن چند مقدار از یک تابع یا گروهبندی دادههای مرتبط بسیار کاربردی است.
دسترسی به عناصر tuple معمولاً از طریق اندیس انجام میشود و Rust این اندیسها را در زمان کامپایل بررسی میکند. این موضوع باعث میشود خطاهای مربوط به دسترسی نادرست به دادهها قبل از اجرا شناسایی شوند. tupleها یکی از ابزارهای ساده اما بسیار قدرتمند Rust هستند.
let user: (i32, bool, char) = (1, true, 'A');
array در Rust و تفاوت آن با tuple
array در Rust مجموعهای از عناصر با نوع یکسان و اندازه ثابت است. برخلاف tuple که میتواند شامل انواع مختلف باشد، همه عناصر array باید از یک نوع باشند. اندازه array نیز در زمان کامپایل مشخص میشود و این موضوع باعث افزایش ایمنی و performance میشود.
arrayها برای دادههایی که تعداد عناصر آنها ثابت است انتخاب مناسبی هستند. Rust بررسی میکند که دسترسی به عناصر array خارج از محدوده انجام نشود و در صورت بروز خطا، برنامه را متوقف میکند. این رفتار جلوی بسیاری از باگهای خطرناک را میگیرد که در زبانهای دیگر ممکن است باعث مشکلات امنیتی شوند.