البرمجة

الحزم والوحدات في لغة رست

الحزم والوحدات المصرفة في لغة رست Rust: بنية التنظيم والتحزيم في تطوير البرمجيات

تُعدّ لغة رست (Rust) من أكثر لغات البرمجة تطورًا في العصر الحديث، ليس فقط لما توفره من أمان في الذاكرة (Memory Safety) وكفاءة في الأداء، ولكن أيضًا بسبب بنيتها المتقدمة في تنظيم الشيفرات المصدرية وإدارة التبعيات من خلال مفهومي “الحزم” (Packages) و”الوحدات المصرفة” (Crates). هذان المفهومان يشكلان العمود الفقري لبنية المشاريع في رست، ويسمحان للمطورين ببناء تطبيقات قابلة للتوسع وسهلة الصيانة، سواء كانت صغيرة الحجم أو على مستوى نظم تشغيل كاملة.

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


أولًا: الوحدة المصرفة Crate – الوحدة البنيوية الأساسية في رست

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

تنقسم الوحدات المصرفة إلى نوعين رئيسيين:

1. وحدة تنفيذية (Binary Crate)

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

2. وحدة مكتبية (Library Crate)

لا تحتوي هذه الوحدة على دالة main، بل تهدف إلى توفير وظائف يمكن استخدامها من وحدات أخرى. وهي التي تُستخدم لبناء مكتبات قابلة لإعادة الاستخدام.

تركيب وحدة Crate

كل Crate لها نقطة بداية تُسمى الجذر (Root). وهي ملف مصدر واحد فقط. في حالة المكتبات يكون عادة src/lib.rs، وفي حالة البرامج التنفيذية يكون src/main.rs. هذا الملف يُمثل مدخل الوحدة المصرفة، ويُستخدم فيه نظام الوحدات (Modules) لتنظيم بقية الشيفرة.


ثانيًا: الحزمة Package – تجميع منطقي للوحدات المصرفة

الحزمة (Package) هي كيان على مستوى أعلى من الوحدة المصرفة. يمكن تعريفها بأنها مجموعة من الملفات والبيانات التي تُستخدم لتجميع وحدة واحدة أو أكثر من الوحدات المصرفة Crates في كيان واحد متكامل. الحزمة يجب أن تحتوي على ملف واحد على الأقل من نوع Crate.

مكونات الحزمة

  1. Cargo.toml: الملف المركزي في الحزمة، يحتوي على معلومات الحزمة مثل الاسم والإصدار والمؤلف والتبعيات.

  2. src/: المجلد الرئيسي الذي يحتوي على ملفات الشيفرة المصدرية.

  3. README.md / LICENSE / .gitignore: ملفات توثيقية وتنظيمية.

قيود الحزم

  • لا يمكن أن تحتوي الحزمة الواحدة على أكثر من مكتبة واحدة (Library Crate).

  • يمكن أن تحتوي الحزمة على أكثر من وحدة تنفيذية (Binary Crates)، يتم تنظيمها داخل مجلد src/bin.


العلاقة بين الحزم والوحدات المصرفة

يمكن تصور العلاقة على الشكل التالي:

العنصر الوصف
Crate وحدة قابلة للترجمة، تنتج إما مكتبة أو برنامجًا تنفيذيًا.
Package مجموعة من واحد أو أكثر من الوحدات المصرفة (Crates) مع ملف إعدادات Cargo.
Project المشروع البرمجي الذي يحتوي على Package، وقد يحتوي على Sub-Packages أو تبعيات.

كل Crate هو جزء من Package، ولكن ليس كل Package يمكن أن يحتوي على أكثر من Crate مكتبي.


إدارة الحزم والوحدات عبر نظام Cargo

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

أوامر Cargo الشائعة

  • cargo new nome_do_projeto: لإنشاء حزمة جديدة.

  • cargo build: لترجمة المشروع.

  • cargo run: لتشغيل البرنامج.

  • cargo test: لتنفيذ اختبارات الوحدة.

  • cargo doc --open: لإنشاء وثائق المشروع.

  • cargo publish: لنشر الحزمة في مستودع crates.io.


تنظيم الشيفرة ضمن الحزم والوحدات المصرفة

يتميز نظام الوحدات في رست بمرونة عالية في تنظيم الشيفرة ضمن الحزمة الواحدة. يمكن تنظيم الملفات على النحو التالي:

less
my_project/ ├── Cargo.toml └── src/ ├── main.rs // Crate تنفيذي ├── lib.rs // Crate مكتبي ├── module1.rs ├── module2/ │ ├── mod.rs │ └── sub_module.rs └── bin/ ├── tool1.rs // برامج تنفيذية إضافية └── tool2.rs

يتيح هذا التنظيم فصل المنطق البرمجي إلى وحدات مستقلة (Modules)، تُحمّل باستخدام الكلمة المفتاحية mod، ويتم استيرادها باستخدام use.


نشر الحزم ومشاركة Crates عبر crates.io

توفر لغة رست مستودعًا مركزيًا باسم crates.io يُعد النظير لمنصة npm في JavaScript أو pip في Python. يسمح هذا المستودع بمشاركة مكتبات رست مع المجتمع أو استخدامها كمكتبات خارجية (Dependencies) في مشاريع أخرى.

خطوات النشر

  1. تسجيل الدخول في الموقع.

  2. إضافة بيانات النشر في Cargo.toml (مثل الوصف، الكلمات المفتاحية، النوع).

  3. تنفيذ الأمر cargo publish.

عند النشر، تُصبح الحزمة متاحة للتحميل من قبل الآخرين باستخدام cargo add اسم_الحزمة.


تبعيات الحزم والإصدارات SemVer

يستخدم نظام Cargo معيار SemVer (Semantic Versioning) لإدارة الإصدارات والتوافقية. ويُستخدم الملف Cargo.toml لتحديد التبعيات المطلوبة للمشروع، حيث يمكن تحديد:

  • اسم الحزمة

  • الإصدار

  • مصدر الحزمة (من crates.io أو Git)

مثال:

toml
[dependencies] serde = "1.0" rand = { version = "0.8", features = ["std"] }

هذا يسمح بمرونة في التطوير، حيث يتم تحديث التبعيات تلقائيًا في حدود الإصدارات المتوافقة (مثلاً، “1.0” تعني أي إصدار من 1.0 إلى أقل من 2.0).


أهمية الحزم والوحدات المصرفة في هندسة البرمجيات

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

  • يمكن فصل المنطق البرمجي في وحدات مستقلة.

  • يمكن مشاركة المكتبات مع المجتمع.

  • يمكن تطوير المشاريع بتعدد الوحدات التنفيذية ضمن نفس الحزمة.

  • يمكن تقليل وقت الترجمة عبر إعادة استخدام الأجزاء المترجمة سابقًا.

  • يمكن للفرق البرمجية التعاون بسهولة باستخدام واجهات واضحة تفصل كل وحدة.


جدول مقارنة بين Crate وPackage

المعيار Crate (وحدة مصرفة) Package (حزمة)
طبيعة الكيان وحدة ترجمة مستقلة مجموعة تحتوي على واحد أو أكثر من Crates
الملف الرئيسي main.rs أو lib.rs Cargo.toml
إمكانية التعدد كل Crate وحدة واحدة فقط يمكن أن تحتوي على Crates متعددة
نوع الناتج مكتبة أو برنامج تنفيذي مشروع متكامل
قابلية النشر يمكن نشره إذا كان ضمن Package يُنشر عبر crates.io

حالات استخدام متقدمة

في المشاريع الكبيرة، قد يُستخدم ما يُعرف بـ “workspace” وهو نظام يتيح تجميع عدة حزم ضمن مشروع واحد، لتسهيل الإدارة، المشاركة في تبعيات، وتسريع الترجمة.

مثال على مشروع يستخدم workspace:

cpp
my_workspace/ ├── Cargo.toml // يحتوي على تعريف workspace ├── package1/ │ └── Cargo.toml └── package2/ └── Cargo.toml

في هذه الحالة، يمكن تنفيذ أمر cargo build من الجذر لتجميع جميع الحزم الفرعية دفعة واحدة، وهو ما يفيد كثيرًا في إدارة المشاريع الضخمة مثل أنظمة التشغيل أو المحاكيات أو الحزم متعددة الواجهات.


الختام

تمثل الحزم (Packages) والوحدات المصرفة (Crates) في لغة رست حجر الزاوية في بنيتها المعمارية، حيث يوفران إطارًا قويًا ومنظمًا لتطوير البرمجيات بطريقة آمنة، مرنة، وقابلة للتوسع. بفضل نظام Cargo والمستودع المركزي crates.io، يمكن للمطورين البناء والمشاركة بسرعة وكفاءة. هذه المزايا تجعل رست لغة متقدمة ليس فقط في الأداء والأمان، بل في إدارة المشاريع البرمجية المعقدة أيضًا.


المراجع:

  1. The Rust Programming Language Book – https://doc.rust-lang.org/book/

  2. Cargo and Crates documentation – https://doc.rust-lang.org/cargo/