دوستدار نرمافزار، فلسفه و ادبیات. وب سایت:http://www.alihoseiny.ir
چرا باید همین امروز زبان Rust را یادبگیریم؟
به خاطر مجموعهی آموزشیای که دارم برای زبان Rust آماده میکنم، این سؤال زیاد از من پرسیده میشود که چرا باید Rust یادبگیریم؟ خیلیها دوست دارند بدانند که یادگرفتن Rust چه کمکی به آنها میکند. برای خیلیها هم این سؤال وجود دارد که چرا به جای C، ++C یا زبانهای دیگری مثل Go باید به سراغ Rust برویم؟
خب حالا میخواهیم با هم ببینیم که چرا باید Rust یادگرفت و چرا ما به چنین زبانی نیازداریم.
در این نوشته هم ویژگیهای Rust را با هم مرور میکنیم و هم کمی آن را با زبانهای C و Go مقایسه میکنیم.
نصیحت پیر ژندهپوش سپید موی صد کیبرد دریده
و پیر چون به بستر مرگ افتاد، فرزندان را یک به یک خواست که پدر را پیش از مرگ نصیحتی است با شما.
فرزندان بر سر زدی و گریستی که ای پدر بر ما بگوی آنچه راز فرزانگیات بود.
پیر گفت: «راز فرزانگی من این بود که هرگز حلقهی عشق زبانی را بر گردن نیفکندم. هر کدام را ابزاری دیدم در دستان خود و از هریک در جای خود استفاده کردم که عاقبت الحاح بر زبانی فانی جز سرشکستگی و نابودی نیست و صلاح هر دولوپر بر آن است که ابزار را بداند و مسئله را دوست بدارد، نه اینکه زبان را بپرستد و اعظام دارد و بر جهل خود اصرار ورزد تا مسئله را هلاک سازد.»
پیر این گفت و چشم فرو بست و فرزندان برایش مقبرهای ساختند که بر آن لوحی بود که هرکه از آن گذشتی آن را بدیدی:
ای انسان، هرآنکه هستی و از هر کجا که میآیی، زیرا میدانم که خواهی آمد، منم دولوپری که کاربران را این برنامه بنیاد کردم، پس بر این مشتی کد که سورس مرا پوشانده دل مبند.
تاریخچهی ۳۰ ثانیهای Rust
انگار همین دیروز بود که آقای Graydon Hoare برای سرگمی ساخت زبان Rust را شروع کرد. حالا دقیقاً دیروزِ دیروز که نه، سال ۲۰۰۶.
وقتی نتیجهی کارش را به مدیرش نشان داد، جناب مدیر از کار خوشش آمد و کمکم کار به جایی رسید که شرکت فخیمهی Mozilla این پروژه را برای نوسازی استک ساخت مرورگرش (firefox) انتخاب کرد.
هدف از استک جدید، توسعه با تکنولوژیهایی ایمنتر، سادهتر و concurrentتر بود. چیزهایی که ++C آنها را برای موزیلا فراهم نمیکرد.
چرا Hoare این زبان را ساخت؟ چون فکر میکرد که خیلی از ایدههای خوب به صورت یکجا در یک زبان سیستمی پیادهسازی نشده اند. اگر هم فیچرهای خوب در این زبانها وجود داشت، در عوض مدل حافظهی ضعیفی داشتند.
کجاها میتوان از Rust استفاده کرد؟
زبان Rust یک زبان برنامهنویسی سیستمی است. یعنی به صورت پیشفرض هرجایی که در کامپیوتر از C استفاده میکردند، میتوان از Rust هم استفاده کرد.
به علاوه در سیستمهای نهفته (embeded)، ابزارهای Command Line، شبکه و البته نرمافزارهای سمت کاربر (به مدد WebAssembly) میتوان از Rust استفاده کرد.
یعنی تقریباً در تمامی زمینهها Rust کاربرد دارد.
Rust چه ویژگیهایی دارد
زبان Rust ویژگیهای خیلی زیادی دارد. امّا چه ویژگیهایی هستند که آن را منحصر به فرد ساخته اند و باعث شده اند که این زبان، زبانی باشد که همهی ما باید آن را یاد بگیریم؟
در اینجا من ۸ ویژگی مختلف را لیست کرده ام. فکر میکنم اینها مهمترین ویژگیهای این زبان اند:
ارورهایی برای فهمیدن راه حل
وقتی شما میخواهید کدی را که به زبان Rust نوشتهاید کامپایل کنید، کامپایلر و Static Analyzer دست به دست هم میدهند تا مطمئن شوند که کدی که نوشتهاید ایمن و درست است.
اگر دچار خطایی در کد شده باشید، مثل بقیهی زبانها، با پیام خطایی مواجه میشوید که میگوید کامپایلکردن این برنامه با شکست مواجه شده است. خب تا اینجای کار که همه چیز طبیعی است.
امّا پیامهای خطای Rust فرق میکنند. پیامهای خطایی که هنگام به مشکل خوردن کامپایل دریافت میکنیم، کامل و دقیق مشکل را توضیح میدهند و در بسیاری از موارد یادآوری میکنند که چطوری میتوان این مشکل را برطرف کرد.
برعکس خیلی از زبانهای دیگر که فقط به رخدادن خطا اشاره میکنند و هیچ سرنخی از اینکه خطا کجاست و چرا اتّفاق افتاده نمیدهند.
در حقیقت کامپایلر Rust مثل یک همکار کنار ما مینشیند و هرجایی که اشتباه کرده باشیم را به ما نشان میدهد و به جای طرح معما برای پیداکردن خطا، خیلی وقتها راه حل را هم معرّفی میکند.
ایمنی
زبان Rust خیال ما را از لحاظ ایمنی در کار با حافظه راحت میکند. در Rust توجّه به مفاهیمی مثل Ownership، Borrowing و Lifetime ضروری است. کامپایلر قبل از کامپایل کردن کد مطمئن میشود که کد شما ایمن است و کار اشتباهی با حافظه نکردهاید.
با این حساب دیگر خبری از مشکلاتی مثل Dangling reference، Data race و … نیست.
به علاوه Rust نیاز به مدیریت حافظه را به صورت دستی از بین برده است. پس دیگر خبری هم از Memory Leak نخواهد بود. تازه در Rust حتّی از Garbage Collector هم خبری نیست، پس این کارها سرباری هم به برنامه اضافه نمیکنند.
یکی از اهداف اصلی Rust این است که شما بتوانید بدون ترس برنامههای concurrent بنویسید. با مکانیزمهایی که معرّفی کردیم و البته بقیهی امکاناتی که Rust در اختیار ما میگذارد، میتوانید concurrency را به صورت کاملاً ایمن و البته بسیار سریع در برنامهتان قرار بدهید.
پس با Rust دیگر خبری از اشتباهاتی که در برنامههای multi-thread روزها وقت توسعهدهندهها را میگرفت نیست و وقتی برنامه کامپایل شد، میتوانید تقریباً مطمئن باشید که مشکلی از این لحاظ ندارد.
Cargo
Rust یک زبان مدرن است. پس مثل بقیهی زبانهای مدرن برای خودش package manager دارد.
این یعنی دیگر لازم نیست برای مدیریت dependencyها ساعتها وقت بگذارید و با build system های وحشتناک سر و کلّه بزنید.
n میلیون فایل make را که باید به هم پیوند بخورند تا برنامه را بتوان build کرد فراموش کنید. حالا شما با Rust به هیچ کدام از این ها نیازی ندارید. تنها کاری که باید انجام بدهید نوشتن یک خط دستور build در ترمینال است. بقیهی چیزها خودش حل میشود.
وجود Cargo باعث میشود که استفاده از پکیجهای بیرونی خیلی خیلی ساده بشود. به سادگی استفاده از پکیجهای node یا پایتون.
ماژولاریتی و قابلیّت توسعه
Rust قابلیّتهای خوبی برای نظمدهی به کد دارد که باعث میشود کدها خیلی بیشتر توسعهپذیر باشند.
شما میتوانید با تعریف ماژولها بخشهای مختلف کد را از هم جداکنید. به علاوه امکان پیادهسازی مفاهیمی مثل encapsulation را هم به شما میدهد.
شما میتوانید ساختارها و enum ها را با متدها و تابع مرتبط تعریف کنید. اینطوری اعمال مربوط به هر نوع به خود آن سنجاق شده است و کدتان ساختار خیلی بهتری دارد.
توسعهدهندگان زبان Rust سعی کرده اند که از اشتباهات و کاستیهای زبانهای قبلی درس بگیرند. به همین خاطر مشکلاتی مثل ساختارمند نبودن کد در زبانهای سطح پایین را حل کرده اند.
سادگی بیشتر
کد زدن به زبان Rust نسبت به خیلی از زبانهای سطح پایین مثل C یا حتّی زبانهایی مثل ++C سادهتر است.
مثلاً شما لازم نیست واقعاً برای تمامی متغیّرها type تعریف کنید. در اکثر موارد خود کامپایلر از روی مقداری که درون متغیّر ریخته شده است نوع آن را میفهمد.
البته حواستان باشد که Rust یک زبان Strongly typed است و بر خلاف C، شما نمیتوانید راحت type system را دور بزنید.
چیز دیگری که Rust را ساده میکند این است که خیلی اوقات میتوانید با نوشتن کد کمتری به نتیجهای مشابه با C برسید.
مثلاً فرض کنید که میخواهیم برنامه ای به زبان C بنویسیم که اگر تمام رشتهی ورودی whitespace بود، مقدار true را برگرداند (این مثال از این ویدیو گرفته شده است)
خب حالا دقیقاً همین کار را میتوان در این دو خط در Rust انجام داد:
داشتن بخشی از مفاهیم شیگرایی
Rust یک زبان سطح پایین است و طبیعتاً شیگرا نیست. امّا برخی از مفاهیم شیگرایی درون این زبان وجود دارند که هم خوانایی کد را بیشتر میکنند و هم کمک میکنند که ما سریعتر و بهتر کد بزنیم.
مثلاً شما میتوانید با استفاده از trait ها یکجورهایی مفهوم inheritance را داشته باشید. شما میتوانید شکلی از encapsulation را درون ماژولها پیادهسازی کنید و از همه جالبتر اینکه قابلیّت استفاده از Polymorphism را هم در Rust دارید.
یعنی شما همچنان با یک زبان سطح پایین خیلی سریع طرف هستید که ویژگیهای functional programming را دارد، امّا میتوانید از مزایای شیگرایی هم تا حدّی استفاده کنید.
سریع و بدون سربار
زبان Rust زبان خیلی سریعی است. با توجّه به کاربرد، شما میتوانید نتایج تستهای مختلف را بررسی کنید و ببیند که سرعت اجرای Rust اغلب نزدیک به C است. حالا در بعضی تستها کمی بالاتر و در بعضی کمی پایینتر.
زبان Rust تقریباً Runtime ندارد (هر زبانی سطح بالاتر از اسمبلی حتماً runtime دارد، امّا زبانهایی مثل Rust و C کوچکترین حالتش را دارند). به علاوه به خاطر نداشتن Garbage Collector و البته ویژگیهای دیگر سربار خیلی کمی دارد.
عملاً به خاطر ویژگی Abstraction بدون هزینهای که دارد، میتوانیم Rust را بدون سربار درنظر بگیریم.
همهی این ویژگیها باعث میشوند که Rust زبانی بسیار سریع و کارا باشد.
دوستداشتنی و روبهرشد
۲۰۱۶، ۲۰۱۷، ۲۰۱۸ و ۲۰۱۹ سالهایی است که Rust دوستداشتنیترین زبان در نظرسنجی StackOverflow بوده است.
به علاوه طبق آخرین آمار گیتهاب، پنجمین زبان روبهرشد محسوب میشود.
خیلی از پروژهها در حال بازنویسی به زبان Rust هستند و بازار کارش، البته به آرامی، در حال رشد است.
اگر امروز Rust یادبگرید، فردا جزو اوّلین کسانی خواهید بود که میتوانند موقعیّتهای شغلی پردرآمد آن را تصاحب کنند.
مقایسهی سریع Rust با C
به خاطر اینکه کامپایلر شما را مجبور میکند تا از روشهای درست پیش بروید و جلوی خطاهای شما را میگیرد، برخلاف خیلی از برنامههای C، برنامهای که با Rust نوشته میشود شانسی اجرا نمیشود .
البته ایمنی چیزی نیست که برنامهنویسان واقعاً حرفهای C را راضی نگهدارد (بله، بله، همهی آن خطاها وسط کدهایتان از آسمان ریخته پایین).
شما هنگام استفاده از Rust دیگر از شر میلیاردها فایل header خلاص میشوید. به علاوه به مدد cargo نیازی به تحمّل هزار جور دردسر برای مدیریت dependency ها و سر و کلّه زدن با فایلهای طولانی make و… ندارید.
Rust یک زبان مدرن است که برای پردازندههای مدرن ساخته شده است. Abstract Machine زبان C برای پردازندههای دههها پیش ساخته شده است. به همین دلیل خیلی اوقات نمیتواند بهترین استفاده را از قابلیّتهای این پردازندهها بکند.
هرچند که در C11 تلاشهایی برای بهبود این شرایط انجام شده است، امّا هنوز مسیر زیادی تا رسیدن به نتیجهی دلخواه وجود دارد. و مسئله این است که به خاطر حجم عظیم کدی که باید تغییر کند، تغییرات صد در صدی دور از ذهن به نظر میرسند.
بخشی از این مشکلات را میتوانید به ++C هم تعمیم بدهید.
مقایسهی سریغ Rust با Go
زبان Go هم زبان نسبتاً جدیدی است که کاربران خیلی زیادی دارد، بیشتر از Rust. خیلیها، مخصوصاً در حوزهی وب، به سمت استفاده از Go رفته اند و همه هم از آن راضی اند.
Rust بر خلاف Go چیزی به نام Garbage Collector ندارد. پس سربارهای ناشی از آن هم در Rust وجود ندارد.
در عوض، Rust امکان استفاده از Generic ها را به شما میدهد. چیزی که متأسفانه در زبان Go وجود ندارد. به علاوه runtime زبان Rust خیلی کمتر از زبان Go است.
سخن پایانی برای کسانی که هنوز قانع نشده اند
یادگرفتن زبان Rust ارزشش را دارد. حتّی اگر هرگز از آن استفاده نکنید.
Rust به شما هدیهای بزرگتر و مهمتر از سرعت یا کارایی میدهد. وقتی که بتوانید به Rust کد بزنید، درون ذهنتان الگوهای درست و خوب کد زدن نهادینه شده است.
Rust در شما ذهنیّت کدنویسی درست، اصولی و به نحوی تمیز را ایجاد میکند. ذهنیّتی که همیشه همراهتان خواهد بود. مهم نیست که به چه زبانی کد میزنید.
من فکر میکنم بزرگترین دستاورد Rust همین تغییر ذهنیّت برنامهنویسها است. تغییری از «کار بکنه» به «درست باشه». تغییری که باعث میشود ما نرمافزارهای بهتری بنویسیم.
فراموش نکنید که نوشتن نرمافزار خوب، وظیفهی اخلاقی ما برنامهنویسها است.
از کجا Rust یادبگیرم؟
نسبت به زبانهای دیگر منابع آموزش Rust کم است. امّا اصلاً جای نگرانی نیست. چون همین آموزشهای کم هم همهچیز را به شما یادمیدهند.
خود وبسایت Rust، کتاب Rust را آماده کرده است که با خواندن آن میتوانید اکثر مفاهیم زبان را یادبگیرید.
برای درک بهتر، دیدن مثالهای بیشتر و یادگرفتن بیشتر جزئیّات هم میتوانید به مجموعهی آموزشی زبان Rust من که در همین وبلاگ منتشر میشود مراجعه کنید.
خوانندگان قبلیاش که تا اینجا از آن راضی بوده اند، امیدوارم شما هم از خواندنش بتوانید لذّت ببرید.
برای رفتن به این مجموعهی آموزشی میتوانید روی همین نوشته کلیک کنید.
اگر هنوز سؤالی درمورد یادگیری Rust در ذهنتان وجود دارد یا نظری در این مورد دارید، همین پایین صفحه و در بخش دیدگاهها، آن را با من و دیگر خوانندگان این نوشته به اشتراک بگذارید. از دیدن پیامهایتان خیلی خوشحال میشوم ? .
مطلبی دیگر از این انتشارات
بخش سوم، یک برنامه ساده با Python Flask Framework
مطلبی دیگر از این انتشارات
آموزش زبان برنامهنویسی Rust – قسمت۱۰- شروع کار با Struct
مطلبی دیگر از این انتشارات
تفاوت عبارت Dynamic و Var در زبان #C - بخش اول