العام الذي تم فيه تقديم لغة البرمجة الصدأ. ما هو الوضع الحالي للغة الصدأ؟ معالجة الأخطاء المفيدة القياسية

08.09.2023

لذلك، نود أن نقدم انتباهكم إلى صبي عيد ميلاد حديث (بلغ من العمر سنة واحدة في 15 مايو 2016) - الصدأ. هذه لغة برمجة عالمية طورتها شركة Mozilla، وتتمثل مبادئها الثلاثة الرئيسية في: السرعة والأمان وبيئة العمل. يعتبره المبدعون أنفسهم بشكل غير محتشم واحدًا من أكثر خلفاء C/C++ احتمالًا. وفقًا لاستطلاع للرأي أجري على StackOverflow، فإن لغة Rust هي اللغة المفضلة لدى المطورين اليوم. لذلك، دعونا نلقي نظرة فاحصة على ما هو عليه.

الصدأ للمبتدئين

لا أريد أن أخدع أحدًا، لذا إليك عبارة مسؤولة: من الصعب جدًا تعلم الصدأ. أولاً، يرجع ذلك إلى حداثة اللغة، ونتيجة لذلك، قلة الأدب. ثانيًا، قد يكون من الأسهل على شخص بعيد عن البرمجة أن يتعلمها أكثر من شخص مطلع على لغات أخرى. لذلك، على سبيل المثال، سيكون أخصائي تكنولوجيا المعلومات الجاهز منزعجا للغاية من الحاجة إلى وصف أدنى العمليات، وغياب الميراث على هذا النحو في اللغة سوف يربكه ببساطة.

ومع ذلك، فإن Rust يتطور بسرعة (يتم إصدار إصدار جديد كل 6 أسابيع)، وينمو المجتمع، ولم يعد العثور على المعلومات على الإنترنت أمرًا صعبًا.

كيفية الدراسة

يمكنك العثور على كل ما تحتاجه تقريبًا على الموقع الرسمي. بالإضافة إلى ذلك، فإن مجتمع متابعي Rust كبير جدًا وودود، لذا يمكنك دائمًا اللجوء إلى IRC (يوجد قسم روسي) والمنتدى الرسمي للحصول على المشورة. بالإضافة إلى ذلك، بدأت الكتب، بما فيها الإلكترونية، بالظهور شيئًا فشيئًا. لا يزال من الصعب تقييم جودتها، ولكن هذه حقيقة.

بالنسبة لأولئك الذين اجتازوا المرحلة الأولية للتعرف، يمكنك العثور على الكثير من المواد المفيدة على GiHub، بما في ذلك RFCs والالتزامات. بالإضافة إلى ذلك، يمكنك الحضور شخصيًا أو على الأقل مشاهدة البث عبر الإنترنت لأحد مؤتمرات Rust المقرر عقدها في النصف الثاني من العام. هنا هو التقويم:

  • 9-10 سبتمبر: مؤتمر RustConf في بورتلاند، الولايات المتحدة الأمريكية؛
  • 17 سبتمبر، مؤتمر RustFest للمجتمعات الأوروبية في برلين، ألمانيا؛
  • 27 أكتوبر: مؤتمر الصدأ في حزام الصدأ في بيتسبرغ، الولايات المتحدة الأمريكية؛

حسنًا، لمقابلة أولئك الذين يعتبرون Rust مكالمتهم، وفي الوقت نفسه اطلب منهم كل حكمتهم، يمكنك الاتصال بالمنظمين والمشاركين في اجتماعات محبي اللغة في موسكو.

الخصائص

تكرار ما قيل سابقًا قليلًا، سنسلط الضوء على الإيجابيات والسلبيات الرئيسية للغة الصدأ.

الايجابيات:

  • العمل الآمن مع الذاكرة؛
  • أداء عالي؛
  • نوع البيانات الجبرية؛
  • إمكانية التنبؤ بالتجميع؛

السلبيات:

  • بعض التكرار في التعليمات البرمجية؛
  • كثافة عالية في تطوير اللغة، ونتيجة لذلك، الافتقار إلى الأدبيات الجيدة ذات الصلة بالدراسة؛
  • الحاجة إلى تحديد معلمات التجميع بشكل واضح لا لبس فيه.

في الواقع، تعتاد بسرعة على الاختلافات، مثل استبدال الميراث بالقدرات. بمجرد أن تعتاد عيناك عليها وتعتاد يديك عليها، تتحول لغة Rust إلى لغة عمل كاملة، أبسط وأكثر وظيفية من لغة C++، ولكنها أدنى في "الجمال" من العديد من لغات البرمجة الأخرى. في الواقع، الفرق الرئيسي بين Rust ومنافسيها وأسلافها هو السرعة والأمان.

يطلب

تحظى Rust اليوم بشعبية كبيرة بين مطوري الألعاب والرسومات وأنظمة التشغيل. ومع ذلك، ولأسباب واضحة، فإن عدد الأماكن الثابتة التي تتطلب خبراء متخصصين للغاية في مجال الصدأ صغير للغاية في العالم، بل وأكثر من ذلك في روسيا. ومع ذلك، لا توجد دلائل حتى الآن على أن اللغة ستغرق في غياهب النسيان؛ فهي تبدو أشبه باستيلاء منهجي على العالم. هذا يعني أن المهارات الجيدة في استخدام Rust في المستقبل ستساعدك في العثور على وظيفة جيدة الأجر ومثيرة للاهتمام في بلدنا وفي الخارج.

لا يزال الطلب عليها: المهنة "".

ترجمة مقال بقلم فيديريكو مينا كوينتيرو، الذي أسس مع ميغيل دي إيكازا مشروع جنوم - بيئة رسومية مجانية مستخدمة على نطاق واسع، خاصة لأنظمة جنو/لينكس. قبل ذلك، كان يدعم برنامج جيمب لبعض الوقت. يعمل Federico حاليًا على تطوير مكتبة librsvg باستخدام لغة البرمجة Rust. في رأيه، وصل التطوير إلى نقطة حيث يبدو نقل بعض المكونات الكبيرة من لغة C إلى Rust مهمة أسهل من مجرد إضافة أدوات الوصول إليها. غالبًا ما يتعين على Federico التبديل من C إلى Rust والعودة، وفي المقالة يتحدث عن سبب اعتباره لغة C لغة بدائية جدًا للبرامج الحديثة.

نوع من المرثية لـ C

لقد وقعت في حب لغة البرمجة C منذ حوالي 24 عامًا. لقد تعلمت الأساسيات من خلال قراءة الترجمة الإسبانية للطبعة الثانية من كتاب لغة البرمجة C (K&R) لكيرنيغان/ريتشي. قبل ذلك، كتبت بلغة Turbo Pascal بطريقة منخفضة المستوى إلى حد ما - باستخدام المؤشرات وتخصيص الذاكرة يدويًا. لقد ترك C يشعر بالانتعاش والقوة.

يعد K&R كتابًا ممتازًا نظرًا لأسلوب كتابته وبرمجته المختصرة. يعلم هذا الكتاب أيضًا كيفية تنفيذ وظائف malloc/free البسيطة، وهو أمر مفيد للغاية. حتى البنيات ذات المستوى المنخفض التي تبدو وكأنها جزء من اللغة يمكن تنفيذها في اللغة نفسها!

وفي السنوات التالية، أصبحت ماهرًا في لغة C. وهي لغة بسيطة بها مكتبة قياسية صغيرة. ربما كانت اللغة المثالية لتنفيذ نواة يونكس في 20000 سطر من التعليمات البرمجية أو نحو ذلك.

لقد علمني GIMP وGTK+ كيفية استخدام النهج الموجه نحو الكائنات في لغة C. وأظهر لي جنوم كيفية دعم المشاريع واسعة النطاق المكتوبة بلغة C. وبدأت أشعر أن 20000 سطر من كود C كان مشروعًا يمكن فهمه بالكامل تقريبًا في غضون اسبوعين .

لكن قواعد الأكواد لدينا لم تعد صغيرة جدًا. حاليا في عملية تطوير البرمجيات ضخمالآمال معلقة على الوظائف المتوفرة في المكتبة القياسية للغة.

تجربة استخدام C

إيجابي

  • قراءة الكود المصدري لمشروع POV-Ray لأول مرة وتعلم كيفية استخدام النهج الموجه للكائنات والميراث في لغة C النقية؛
  • قراءة الكود المصدري لمشروع GTK+ وتعلم أسلوب ترميز C سهل القراءة وقابل للصيانة ونظيف؛
  • قراءة الكود المصدري لمشروع SIOD بالإضافة إلى الكود المصدري لمشروع Guile المبكر وفهم كيفية كتابة مترجم المخطط بلغة C؛
  • كتابة الإصدارات الأولى من Eye of Gnome ووضع اللمسات الأخيرة على نظام عرض الميكروفيلي.

سلبي

  • العمل ضمن فريق Evolution عندما كان البرنامج يتعطل باستمرار. لقد اضطررنا إلى شراء سيارة وعلى متنها Solaris حتى نتمكن من شراء Purify؛ في تلك الأيام لم يكن فالجريند موجودًا بعد؛
  • تصحيح الجمود في مؤشر الترابط في gnome-vfs؛
  • تصحيح أخطاء ميسا غير ناجح؛
  • عندما حصلت على الكود المصدري للإصدارات الأولى من Nautilus-share، رأيت أن free() لم يتم استخدامه على الإطلاق؛
  • محاولات لإعادة بناء التعليمات البرمجية التي لم يكن لدي أي فكرة عن استراتيجية إدارة الذاكرة الخاصة بها؛
  • محاولة لإنشاء مكتبة من التعليمات البرمجية التي تعج بالمتغيرات العامة والتي لا يتم وضع علامة على أي وظيفة فيها على أنها ثابتة.

ميزات Rust المفقودة في C

إدارة الموارد التلقائية

إحدى أولى التدوينات التي قرأتها عن Rust كانت بعنوان "في Rust، لن تضطر أبدًا إلى إغلاق المقبس". يستعير Rust أفكارًا من لغة C++ حول المصطلح (الاستحواذ على الموارد هو التهيئة) والمؤشرات الذكية، ويضيف ملكية وحيدة للقيم، ويوفر آلية لإدارة الموارد بشكل تلقائي وحتمي في حزمة أنيقة للغاية.

  • تلقائي: لا حاجة للاتصال المجاني () يدويًا. سيتم تحرير الذاكرة، وسيتم إغلاق الملفات، وسيتم إلغاء قفل كائنات المزامنة عندما تخرج المتغيرات عن النطاق. إذا كنت بحاجة إلى كتابة غلاف لمورد جهة خارجية، فكل ما عليك فعله هو تنفيذ سمة الإسقاط. يبدو المورد المغلف وكأنه جزء من اللغة لأنه لا يتعين عليك رعاية فترة بقائه يدويًا؛
  • الحتمية: يتم إنشاء الموارد (تخصيص الذاكرة وتهيئتها، وفتح الملفات، وما إلى ذلك) وتدميرها عندما تخرج عن النطاق. لا يتم تجميع البيانات المهملة: يتم تحرير الموارد فعليًا عند إغلاق القوسين. تبدأ في رؤية عمر البيانات في برنامجك كشجرة من استدعاءات الوظائف.

بعد النسيان المستمر لتحرير/إغلاق/تدمير الكائنات في لغة C، أو، الأسوأ من ذلك، محاولة معرفة مكان وجود رمز شخص آخر، نسوا القيام بأي من هذا (أو فعلوا ذلك عن طريق الخطأ) مرتين)... أنا فقط لا أريد هذا بعد الآن.

الأدوية العامة

فيك هو في الحقيقة متجه حجم عناصره يساوي حجم كائن من النوع T . هذه ليست مجموعة من المؤشرات إلى الكائنات التي تم تخصيص الذاكرة لها بشكل منفصل. تم تجميعه خصيصًا في كود يمكن أن يعمل فقط على كائنات من النوع T.

بعد كتابة الكثير من وحدات الماكرو المشكوك فيها في لغة C للقيام بشيء مماثل... لم أعد أريد ذلك بعد الآن.

السمات هي أكثر من مجرد واجهات

Rust ليست لغة موجهة للكائنات تشبه Java؛ يمكنك قراءة المزيد عن هذا في الكتاب مفتوح المصدر "The Rust Programming Language". بدلاً من ذلك، يحتوي على سمات تشبه في البداية الواجهات في Java، وهي طريقة بسيطة لتنفيذ الإرسال الديناميكي، بحيث إذا قام كائن بتنفيذ Drawable فيمكن افتراض أنه يحتوي على طريقة draw().

ومع ذلك، الأنواع هي أداة أكثر قوة. يمكن اعتبار إحدى السمات المميزة للسمات أنواعًا مرتبطة. على سبيل المثال، يوفر Rust سمة Iterator التي يمكنك تنفيذها:

مكرر سمة Pub (اكتب Item; fn next(&mut self) -> Option ; }

وهذا يعني أنه عندما تقوم بتنفيذ هذه السمة على أي كائن قابل للتكرار، فإنك تحدد أيضًا نوع العنصر للقيم التي ينتجها. إذا اتصلت بـ next() وما زالت هناك عناصر متبقية، فستحصل على Some(YourElementType) . عندما ينفد عنصر التكرار الخاص بك، فإنه سيعود بلا .

يمكن أن تشير الأنواع المرتبطة إلى أنواع أخرى.

على سبيل المثال، في Rust يمكنك استخدام حلقات for مع أي شيء يطبق سمة IntoIterator:

سمة Pub IntoIterator ( /// نوع العناصر المراد تكرارها فوق نوع العنصر؛ /// ما نوع المكرر الذي نقوم بالتحويل إليه؟ اكتب IntoIter: Iterator ; fn into_iter(self) -> Self::IntoIter; )

عند تنفيذ هذه السمة، يجب عليك تحديد نوع العناصر التي سينتجها مكررك ونوع IntoIter نفسه، الذي ينفذ سمة Iterator ويخزن حالة مكررك.

بهذه الطريقة يمكنك بناء شبكة حقيقية من الأنواع التي تشير إلى بعضها البعض. يمكنك كتابة نوع يقول: "يمكنني أن أفعل foo and bar، ولكن فقط إذا أعطيتني نوعًا يمكنه فعل هذا وذاك."

شرائح

لقد كتبت بالفعل عن افتقار لغة C إلى شرائح للعمل مع السلاسل وما هو الصداع الذي تشعر به عندما تعتاد على وضعها في متناول اليد.

الأدوات الحديثة لإدارة التبعية

بدلاً من

  • قم بتشغيل pkg-config يدويًا أو من خلال ماكرو Autotools؛
  • يتضمن القتال مسارات في ملفات الرأس...
  • ... وملفات المكتبة؛
  • وفي الواقع، الاعتماد على المستخدم للتأكد من تثبيت الإصدارات الصحيحة من المكتبات،

تكتب ملف Cargo.toml الذي يسرد أسماء وإصدارات جميع التبعيات لدينا. سيتم تنزيلها من مصدر معروف للعامة أو من أي مصدر آخر تحدده أنت.

ليست هناك حاجة لمحاربة الإدمان. إنه يعمل فقط عندما تكتب بناء البضائع.

الاختبارات

في لغة C، من الصعب جدًا تغطية التعليمات البرمجية بالاختبارات لعدة أسباب:

  • غالبًا ما يتم تمييز الوظائف الداخلية بأنها ثابتة. وهذا يعني أنه لا يمكن استدعاؤها خارج الملف الذي تم تعريف الوظيفة فيه. يضطر برنامج الاختبار إما إلى # تضمين محتويات المصدر الذي تم الإعلان عن الوظيفة فيه، أو استخدام #ifdef لإزالة البيانات الثابتة فقط عند الاختبار؛
  • سيتعين عليك التنقل حول ملف Makefile الخاص بك لربط برنامج الاختبار بجزء معين من التبعيات الرئيسية أو بجزء من بقية البرنامج؛
  • سيكون عليك اختيار إطار الاختبار. سيكون عليك تسجيل اختباراتك في إطار اختبار. سيكون عليك ذلك يذاكرهذا الإطار.

في الصدأ تكتب

# fn test_that_foo_works() ( يؤكد!(foo() == متوقع_النتيجة); )

في أي مكان في برنامج أو مكتبة، وعندما تكتب اختبار الشحن، ينجح الأمر تمامًا. يرتبط هذا الرمز فقط بملف الاختبار القابل للتنفيذ. ليست هناك حاجة لتجميع أي شيء يدويًا مرتين، أو كتابة ملف Makefile السحري، أو معرفة كيفية سحب الوظائف الداخلية للاختبار.

بالنسبة لي، هذه إحدى السمات القاتلة الرئيسية للغة.

التوثيق مع الاختبارات

يقوم Rust بإنشاء وثائق بناءً على التعليقات التي تم ترميزها باستخدام Markdown. رمز من الوثائق يعمل مثل الاختبارات العادية. يمكنك إظهار كيفية استخدام الوظيفة أثناء اختبارها:

/// ضرب الرقم المحدد في اثنين /// /// ``` /// تأكيد_eq!(multiply_by_two(5), 10); /// ``` fn multiply_by_two(x: i32) -> i32 ( x * 2 )

يتم تشغيل رمز المثال كاختبار للتأكد من تحديث الوثائق الخاصة بك باستخدام رمز البرنامج الخاص بك.

وحدات الماكرو الصحية

يحتوي Rust على وحدات ماكرو صحية خاصة لتجنب المشكلات حيث يتم تظليل المعرفات عن غير قصد في التعليمات البرمجية عند توسيع وحدات ماكرو C. لم تعد بحاجة إلى كتابة وحدات ماكرو تحتوي على جميع الأحرف بين قوسين بحد أقصى (5 + 3، 4) لتعمل بشكل صحيح.

لا صب ضمني

كل هذه الأخطاء التي تظهر في لغة C بسبب التحويل غير المقصود لـ int إلى Short أو char، وما إلى ذلك - غير موجودة في Rust. يجب عليك إرسال الأنواع بشكل صريح.

لا يوجد تجاوز لعدد صحيح

هذا يقول كل شيء.

عموما لا يوجد سلوك غير محدد في الوضع الآمن

في Rust، إذا تسبب شيء ما في سلوك غير محدد في "الوضع الآمن" (أي شيء مكتوب خارج كتل unsafe())، فإنه يعتبر خطأ في اللغة نفسها. على سبيل المثال، يمكنك تحويل عدد صحيح سالب إلى اليمين، وسيحدث بالضبط ما تتوقعه.

نمط مطابقة

هل تعرف كيف يحذرك gcc إذا كنت تستخدم Switch() مع التعداد ولكنه لا يعالج جميع الخيارات؟ إنها روضة أطفال مقارنة بالصدأ.

يستخدم الصدأ مطابقة الأنماط في أماكن مختلفة. يمكنه القيام بهذا الشيء باستخدام التعدادات في تعبير المطابقة. وهو يدعم التدمير، مما يعني أنه يمكنك إرجاع قيم متعددة من دالة:

Impl f64 ( pub fn sin_cos(self) -> (f64, f64);) زاوية السماح: f64 = 42.0; دع (sin_angle، cos_angle) = angle.sin_cos();

المباراة تعمل على السلاسل. يمكنك مطابقة الخطوط اللعينة.

دع اللون = "أخضر"؛ مطابقة اللون ( "أحمر" => println!("هذا أحمر"), "أخضر" => println!("هذا أخضر"), _ => println!("شيء آخر"), )

أنت تعرف مدى صعوبة قراءة هذا، أليس كذلك؟

my_func (صواب، خطأ، خطأ)

ماذا عن استخدام مطابقة الأنماط على وسيطات الوظائف بدلاً من ذلك:

هيكل الحانة Fubarize(pub bool); هيكل الحانة Frobnify(حانة bool); هيكل الحانة Bazificate(حانة bool); fn my_func(Fubarize(fub): Fubarize, Frobnify(frob): Frobnify, Bazificate(baz): Bazificate) ( if fub ( ...; ) if frob && baz ( ...; ) ) ... my_func(Fubarize (صحيح)، فروبنيفي (خطأ)، بازفيكاتي (صحيح))؛

معالجة الأخطاء المفيدة القياسية

لقد تناولت هذا بالتفصيل. لا مزيد من قيم الإرجاع المنطقية دون وصف الخطأ المناسب، ولا مزيد من الأخطاء التي يتم تجاهلها عن طريق الخطأ، ولا مزيد من معالجة استثناءات longjmp.

#

إذا كنت تكتب نوعًا جديدًا (على سبيل المثال، بنية تحتوي على مجموعة من الحقول)، فيمكنك كتابة # وسيعرف Rust كيفية طباعة محتويات هذا النوع تلقائيًا لتصحيح الأخطاء. لم تعد بحاجة إلى كتابة وظيفة خاصة يدويًا، والتي يتعين عليك بعد ذلك استدعاؤها من gdb، فقط لعرض محتويات حقول الكتابة المخصصة.

الإغلاق

لم تعد بحاجة إلى تمرير مؤشرات الوظائف وبيانات المستخدم يدويًا.

خاتمة

لم أجرب "التزامن الشجاع" حتى الآن، حيث يمكن للمترجم منع سباقات البيانات في التعليمات البرمجية متعددة الخيوط. أعتقد أن هذا سيغير قواعد اللعبة بالنسبة للأشخاص الذين يكتبون أكوادًا متوازية بشكل منتظم.

لغة C هي لغة قديمة ذات بنيات بدائية وأدوات بدائية. لقد كان مناسبًا تمامًا لنواة يونكس الصغيرة ذات المعالج الواحد والتي تعمل في بيئات أكاديمية موثوقة. لكنها لم تعد مناسبة للبرامج الحديثة.

ليس من السهل تعلم الصدأ، لكنني متأكد من أنه يستحق ذلك. التحدي هو أن اللغة تتطلب منك أن يكون لديك فهم عميق للكود الذي تريد كتابته. أعتقد أنها إحدى تلك اللغات التي تجعلك مبرمجًا أفضل وتتيح لك حل المشكلات الأكثر طموحًا.

يكتسب الصدأ شعبية كبيرة، لكن الكثيرين ما زالوا لا يفهمون قيمته ووظائفه. سنخبرك بالمزايا الرئيسية للغة البرمجة Rust.

ما هو الشيء المشترك بين لغة Rust واللغات الأخرى؟

من الصعب تصديق التعريفات المذكورة أعلاه، ويبدو أنها بيان غير واقعي، حيث أن جميع اللغات في السابق اختارت أحد الجانبين: الموثوقية أو الأداء.

يعد الممثل المذهل للسرعة العالية، لكننا نعلم جميعا عدد المرات التي تظهر فيها الأخطاء بسبب الوصول غير الصحيح إلى الذاكرة المخصصة، والخوادم البعيدة، وليس هناك ما نقوله عن مخرجات نتائج العمل غير المتوقعة. نظرًا لتعدد سلاسل الكتابة، غالبًا ما يكون من الصعب التنبؤ بالنتيجة.

من الأفضل إظهار التحيز نحو الموثوقية من خلال اللغة هاسكل، والتي تم تجميعها بطبيعتها وتوفر أداءً أمنيًا عاليًا. أي شيء يمكن تجميعه سيعمل بشكل صحيح. العيب الرئيسي- هذا أداء منخفض، فمن الصعب تخيل مشروع يتطلب سرعة كتابة عالية هاسكل.

ويحتل الباقي أيضًا موقفًا محايدًا وتوازنًا معينًا. يركزون على التطبيق العملي.

الصدأيتضمن أفضل الخصائص سي ++و هاسكل، وكان قادرًا أيضًا على الحفاظ على التطبيق العملي والوظائف الكافية مقارنة بالمنافسين الآخرين.

ما هو جمال لغة الصدأ؟

يتم توفير الميزات السحرية لـ Rust من خلال أساسيات التجميع ومعلومات كيان المالك ( مالك)، حول مبرمج يقوم بتصحيح الأخطاء مؤقتًا فقط أو يتولى المشروع ( الاقتراض القابل للتغيير) وكذلك عن المشاهد العادي ( الاقتراض غير قابل للتغيير).

عند البرمجة في جافاأو سي ++، عليك الاحتفاظ بهذه المعلومات في الذاكرة، على الرغم من اختلاف نوع البيانات بعض الشيء. في الصدأويتم تنفيذ ذلك باستخدام بنيات اللغة؛ وتسهل هذه المعلومات على المترجم تحديد الهوية واختيار نموذج السلوك بشكل صحيح. باستخدام المترجم، يمكنك التأكد من التخلص من المشكلات المحتملة والشائعة أثناء تنفيذ التعليمات البرمجية.

تتطلب هذه اللغة نهجا مختلفا قليلا. على الرغم من الغرابة، فإن الخوارزمية واضحة وفعالة للغاية. الآن سوف نحدد أساسيات اللغة التي يمكن أن تؤدي إلى طريق مسدود عند البدء في الدراسة:

  1. تم إلغاء نظام الميراث بالكامل، وتم استخدام هيكل وقدرات خاصة لاستبداله، والمزيد من التفاصيل حول السمات.
  2. المؤشرات موجودة حصريًا في التعليمات البرمجية التي لا تخضع لحماية إضافية، أي داخل الدالة unsafe(). لاستبدالها، تستخدم التعليمات البرمجية الآمنة المراجع التي توفر المؤشر الصحيح للكائنات الموجودة.
  3. إذا كان الرابط ثابتًا ويشير إلى عنصر محدد، على سبيل المثال، immutableobject = &Object ، فلا يمكن لأي مستخدم تعديله حتى يموت الرابط.
  4. إذا كان هناك اقتراض قابل للتغيير = &mut رابط كائن يتغير، فلا يمكن لأي مستخدم آخر قراءة المحتويات طوال عمر الارتباط.
  5. يركز المطورون على منصات Mac و*nix، ولهذا السبب فهو يعمل على النظام شبابيكممكن فقط باستخدام بيئة جنو.

الجمهور المستهدف مهم للغاية؛ لغة الصدأ لديها مجتمع نشط إلى حد ما، ونظام اتصال وتدريب متطور. نوصي بزيارة قناة IRC أو Reddit. حتى يومنا هذا، تم كتابتها بالفعل، ولا يزال معظمها قيد التطوير باستمرار، ويمكن العثور على مشاريعها على GitHub.

تحظى اللغة بشعبية كبيرة بين المطورين الذين سلكوا طريق إنشاء الرسومات والألعاب. حتى أن هناك تطورات لإنشاء نظام تشغيل كامل، لكنها لا تزال قيد التطوير. في المستقبل القريب هناك إمكانية لكتابة برامج العميل وخوادم الويب. جميع المهام المذكورة أعلاه تقع بالكامل ضمن قدرات Rust.

العيب الرئيسي، وربما الوحيد، هو تطوره النشط بشكل مفرط. ومع إصدار إصدارات جديدة، يتغير بناء الجملة إلى حد ما، وهناك حاجة بشكل دوري إلى تغيير منطق السلوك والتطوير من أجل التكيف مع الإمكانات الجديدة. سيستمر الوضع لبعض الوقت حتى إصدار Rust-1.0.

العمود العادي " هذا الأسبوع في الصدأ"، والتي يمكن العثور عليها في Rust "n Stuffs على الرابط. هناك دائمًا معلومات حول التغييرات السابقة والماضية، بالإضافة إلى احتمالات تطوير اللغة.

ربما لاحظت الآن أن بناء جملة لغة البرمجة المعنية يشبه إلى حد كبير بناء جملة لغات مثل C/C++، لأنه في كلتا الحالتين يتم استخدام شرطتين مائلتين لتسليط الضوء على التعليقات، وتكون كتل التعليمات البرمجية محاطة بأقواس متعرجة ، والوسائط الوظيفية محاطة بأقواس. تذكر أيضًا أنه يتم استخدام الكلمة الأساسية fn للإعلان عن الوظائف، ويجب أن يحتوي كل برنامج على وظيفة main(). تشير علامة التعجب بعد اسم وظيفة println في هذه الحالة إلى أنه يتم استخدام ماكرو (في الأساس عبارة عن غلاف ملائم حول وظيفة الطباعة من مكتبة وقت تشغيل Rust).

لتجميع البرنامج، ببساطة قم بتشغيل الأمر:

روستك hello.rs

ونتيجة لذلك، يجب أن يظهر ملف ثنائي يسمى hello في الدليل مع ملف التعليمات البرمجية المصدر للبرنامج؛ ولتنفيذه، ما عليك سوى تشغيل الأمر./hello. ولكن إذا انتبهت إلى حجم هذا الملف، فسوف تصاب بالصدمة إلى حد ما: فهو سيتجاوز 800 كيلو بايت. وكل هذا مطلوب لكي يعمل مثل هذا البرنامج البسيط؟ حسنًا، بشكل افتراضي، يقوم مترجم Rust بربط معظم مكتبات وقت التشغيل بشكل ثابت مع البرنامج، بحيث يمكنك نسخ الملف الثنائي إلى نظام لم يتم تثبيت مكتبات وقت تشغيل Rust عليه وتشغيله دون أي مشاكل. ومع ذلك، يمكنك أيضًا إخبار المترجم بإجراء التحسينات والارتباط الديناميكي:

Rustc -O C تفضل hello.rs الديناميكي

الآن سوف تحصل على ملف ثنائي بحجم مقبول أكثر، يساوي 8 كيلو بايت، ولكن إذا كنت تستخدم الأداة المساعدة ldd، فستجد أنه لكي يعمل البرنامج بشكل صحيح، يجب أن تكون مكتبة libstd الديناميكية موجودة على النظام.<версия>.لذا .

بناء جملة لغة البرمجة

الآن بعد أن أصبح بإمكاننا تجميع البرامج وتشغيلها في Rust، أقترح فهم بناء جملة لغة البرمجة هذه وإبراز اختلافاتها عن بناء جملة لغات البرمجة مثل C وC++ وغيرها من اللغات المشابهة:

Fn doubler (x: i32) -> i32 ( x * 2 ) fn main () ( Let a: i32 = 5; Let b; b = doubler(a); println!("a ضرب 2 ()"، b) ; مطابقة ب ( 1 ... 10 => println!("من 1 إلى 10"), _ => println!("رقم آخر"), ) )

إذا كنت معتادًا على العمل بلغات C/C++، فقد تعتقد أن هذا الرمز غريب إلى حد ما، ولكنه منطقي تمامًا. لنبدأ بالوظيفة main(): في السطر الأول من دعونا نعلن عن متغير صحيح 32 بت a ونخصص له قيمة أولية 5. يمكننا تخطي تحديد نوع المتغير (i32 هو نوع المتغير القياسي) وأيضاً عدم تعيين قيمة أولية لها، وفي هذه الحالة ستحتوي على قيمة صفر. لاحظ أنه إذا قمت بتعريف متغير وقمت بتعيين قيمة محددة له بنفس طريقة المتغير a في المثال، فلن تتمكن من تغيير قيمته لاحقًا، لذلك سيتم إنشاء رسالة خطأ عند تجميع مقتطف التعليمات البرمجية التالي:

دع: i32 = 5؛ أ = 10؛

بشكل افتراضي، تكون المتغيرات في Rust غير قابلة للتغيير، مما يعني أن قيمها لا يمكن أن تتغير بعد التهيئة. يجب عليك الإعلان بوضوح عن المتغيرات القابلة للتغيير بطريقة مماثلة:

دع mut a: i32 = 5؛

لماذا هذا مطلوب؟ هذا عمل إضافي، أليس كذلك؟ حسنًا، هذا صحيح في جوهره، ولكن من ناحية أخرى، تساعد هذه الميزة في لغة البرمجة على تطوير برامج آمنة. يجب عليك فقط جعل المتغيرات قابلة للتغيير والتي تحتاج قيمها بالفعل إلى التغيير. يفرض عليك Rust أن تكون مطولا بقدر الضرورة لوصف كيفية عمل البرنامج بأكبر قدر ممكن من الدقة: السطر أعلاه يعلن عن متغير صحيح موقّع a بحجم 32 بت بالضبط، مع إمكانية تغيير قيمته في المستقبل.

بعد ذلك، نسمي الدالة المضاعفة بالمتغير a كوسيطة لها ونخزن القيمة المرجعة في المتغير b. انتبه إلى إعلان الدالة المضاعفة، الموجود في بداية كود البرنامج: فهو يشير إلى نوع معلمة الدالة (i32) ونوع القيمة المرجعة (i32) بعد الرموز ->. من السهل أيضًا أن ترى أن الدالة تنفذ عملية واحدة، x * 2 ، والتي لا تتبعها حتى فاصلة منقوطة، مثل كتلة عادية من كود Rust؛ ما الذي يحدث هناك؟

اتضح أنه يمكنك إرجاع قيمة دالة إما بنفس الطريقة كما في لغة C، أو ببساطة عن طريق وضع التعبير على السطر الأخير من رمز الدالة، كما حدث في هذه الحالة. وبما أن هذا مجرد تعبير، فلا داعي لوضع فاصلة منقوطة بعده.

دعنا نعود إلى الدالة main()، حيث استخدمنا الماكرو println!() لطباعة النتيجة؛ لاحظ تقنية استبدال قيمة متغير باستخدام تسلسل الأحرف (). أخيرًا، يوضح المثال الكلمة الأساسية "match" المفيدة للغاية في لغة برمجة Rust، والتي يمكن أن تقلل بشكل كبير من كمية التعليمات البرمجية إذا كنت بحاجة إلى تنفيذ عدد كبير من عبارات if/else. في هذه الحالة، 1...10 هو إعلان لنطاق من القيم (من 1 إلى 10 ضمناً)، ويطابق حرف الشرطة السفلية (_) جميع القيم الأخرى.

في Rust، يسمح نوع char string باستخدام أحرف ذات أربعة بايت، أي أحرف Unicode، وهذا يعني أنه تم تكييف لغة البرمجة في مرحلة التصميم للعمل مع لغات مختلفة وأحرف خاصة. نوع آخر مفيد من البيانات هو Tuple، وهو عبارة عن مجموعة من المتغيرات من أنواع مختلفة:

دع x = (1, 2.0, "Hello");

في هذه الحالة، يتم وضع قيمة عددية وقيمة عائمة وقيمة سلسلة في نفس الصف. هذه القيم غير قابلة للتغيير ويمكن الوصول إليها بنفس الطريقة:

Println!("()"، x.2);

ونتيجة لذلك، سيتم إخراج قيمة العنصر الثالث من الصف x، أي السلسلة "Hello" . كما هو الحال مع المصفوفات العادية، المدعومة أيضًا في Rust، فإن ترقيم عناصر الصفوف يبدأ من الصفر. يمكنك استخدام الصفوف لإرجاع قيم متعددة من دالة:

مفتاح Fn (الإدخال: (i32، i32)) -> (i32، i32) ( (input.1، input.0)) ) fn main() ( Let x = (10, 50); Let y = Switch(x) ; println!("(), ()", y.0, y.1);

في هذه الحالة، تأخذ دالة تسمى التبديل () صفًا من قيمتين صحيحتين 32 بت وتخزنهما في متغير الإدخال. كما تقوم أيضًا بإرجاع صف يحتوي على قيمتين صحيحتين. تستخدم هذه الوظيفة تعبيرًا بسيطًا يسمح لك بتبديل عناصر الصف وإرجاع الصف الناتج.

تنشئ الدالة main() صفًا باسم x يحتوي على القيمتين 10 و50، وصفًا باسم y يحتوي على القيم التي تم إرجاعها من استدعاء التبديل (). بعد ذلك، يتم عرض قيم الصف ببساطة على الشاشة (50، 10).

نصيحة:إذا كنت ترغب في استكشاف إمكانيات Rust بنفسك، فنوصيك بالبدء بقراءة الوثائق الرسمية الموجودة على https://doc.rust-lang.org/book.

كان هذا وصفًا موجزًا ​​​​لتركيب وإمكانيات لغة البرمجة Rust؛ إذا كنت ترغب في معرفة المزيد عن لغة البرمجة هذه في سلسلة خاصة من المقالات، فأخبرنا بذلك!



اليوم، يتم دعم بناء جملة Rust في vim وemacs باستخدام ملفات بناء الجملة المتوفرة مع المترجم.
هناك أيضًا حزم تركيب للمحرر الشهير Sublime Text 2 والمحرر المجاني Kate. لا يوجد دعم لـ Rust في IDE حتى الآن. يبدو أنه لا يوجد دعم مصحح الأخطاء أيضًا.

يتم توفير الأدوات المساعدة التالية مع المترجم Rustc:
> com.rustdoc- أداة مساعدة لإنشاء الوثائق تلقائيًا من التعليمات البرمجية المصدر مثل Doxygen؛
> com.rustpkg- مدير الحزم الذي يسمح لك بتثبيت الحزم والمكتبات الإضافية بسهولة؛
> روستي- ما يسمى بالأداة المساعدة REPL (حلقة قراءة التقييم والطباعة). هذا هو في الأساس مترجم اختباري يأخذ تعبير Rust من سطر الأوامر، ويجمعه في تمثيل LLVM داخلي، وينفذه، ويطبع النتيجة؛
> الصدأ- أداة مساعدة عالمية تقوم بتشغيل أدوات مساعدة أخرى أو مترجم اعتمادًا على المعلمات. أبدا عملت بالنسبة لي.

يتم جمع كافة الوثائق المتوفرة حول اللغة على الموقع الرسمي www.rust-lang.org. يوجد دليل مفصل (http://static.rust-lang.org/doc/tutorial.html) - وثائق رسمية شاملة عن جميع الفروق الدقيقة في بناء الجملة، ونموذج الذاكرة، ونظام وقت التشغيل، وما إلى ذلك، بالإضافة إلى وثائق حول المكتبة الأساسية المضمنة والمكتبة القياسية std. جميع الوثائق باللغة الإنجليزية. لا توجد مواد حالية باللغة الروسية، وبعض المقالات المراجعة الموجودة قديمة جدًا بالفعل.

الأيديولوجيا وبناء الجملة


Rust هي لغة شبيهة بلغة C تستخدم الأقواس المتعرجة لفصل كتل التعليمات البرمجية. اللغة "متعددة النماذج" أي. يسمح لك بكتابة التعليمات البرمجية بطريقة إجرائية حتمية أو كائنية التوجه أو متزامنة أو وظيفية. يتم تجميع Rust إلى كود ثنائي أصلي على أي نظام أساسي مدعوم (يستخدم LLVM كواجهة خلفية). من الناحية النظرية، يجب أن يكون كود Rust بنفس سرعة كود C/C++. يتم وضع Rust كلغة أنظمة، ولكنها لا تحتوي على دعم مدمج لكتل ​​تعليمات التجميع مثل لغات الأنظمة "الحقيقية" C أو C++ أو D.

لا يسمح نموذج ذاكرة Rust بطبيعته بالمؤشرات الفارغة أو المتدلية وتجاوز سعة المخزن المؤقت. يوجد أداة تجميع البيانات المهملة الاختيارية التي تعمل فقط ضمن سلسلة رسائل واحدة من التعليمات البرمجية. تحتوي اللغة على دعم مدمج للمهام المتعددة خفيفة الوزن والتواصل بين سلاسل الرسائل باستخدام المراسلة. الذاكرة المشتركة غير موجودة في Rust على الإطلاق. يتم تقسيم جميع المتغيرات إلى متغيرات المكدس، ومتغيرات الكومة لخيط معين، وما يسمى بمتغيرات الكومة "التبادلية"، والتي يمكن قراءتها بواسطة جميع الخيوط، ولكن لا يمكن تغييرها بواسطتها. يؤدي هذا تلقائيًا إلى إزالة حالة الجمود، والتي تعتبر آفة البرمجة متعددة الخيوط. تتوافق واجهة برمجة التطبيقات (ABI) الخاصة باللغة مع لغة C، لذلك يمكن ربط برامج Rust بالمكتبات المكتوبة بلغة C بدون أغلفة إضافية. لتلبية احتياجات برمجة النظام ذات المستوى المنخفض ولضمان التوافق مع لغة C، تحتوي اللغة على وضع "غير آمن" خاص دون التحقق من صحة المؤشرات. من حيث أيديولوجيتها، فإن Rust هي الأقرب إلى لغة Go. تمامًا كما هو الحال في Go، ينصب التركيز الرئيسي على بساطة البرمجة متعددة الخيوط وسرعة تطوير التطبيقات واسعة النطاق، كما أن بناء الجملة غير عادي ومثير للدهشة إلى حد ما في بعض الأماكن. وفي الوقت نفسه، فإن Rust ليست بسيطة مثل Go وتدعي أنها لغة نظام.

تم استعارة بناء جملة Rust إلى حد كبير من C وC++، مع خلط بعض الأفكار من Go وC# وHaskell وPython وRuby. لن أصف تركيب اللغة بشكل شامل، لكنني سأركز فقط على المفاهيم الأكثر إثارة للاهتمام.