فهم المفاهيم وراء تنظيم التعليمات البرمجية

مكتمل

قبل أن نبدأ، من المهم شرح المفاهيم وراء تنظيم التعليمات البرمجية في برامج Rust:

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

الحزمة

كلما قمنا بتشغيل الأمر $ cargo new <project-name>، ينشئ Cargo حزمة لنا:

$ cargo new my-project
     Created binary (application) `my-project` package

هنا، لدينا حزمة تحتوي فقط على src/main.rs، ما يعني أنها تحتوي فقط على صندوق ثنائي يسمى my-project:

my-project
├── src
│  └── main.rs
└── Cargo.toml

يمكن أن تحتوي الحزمة على صناديق ثنائية متعددة عن طريق وضع الملفات في src/bin الدليل. سيكون كل ملف صندوقًا ثنائيًا منفصلاً.

إذا كانت الحزمة تحتوي على و src/lib.rs، تحتوي على src/main.rs صندوقين: مكتبة وثنائية. وكلاهما له نفس اسم الحزمة.

الصناديق

يركز نموذج التحويل البرمجي ل Rust على البيانات الاصطناعية التي تسمى الصناديق التي يمكن تحويلها برمجيا إلى ثنائي أو إلى مكتبة.

كل مشروع تقوم بإنشائه باستخدام cargo new الأمر هو صندوق نفسه. كافة تعليمات Rust البرمجية لجهة أخرى والتي يمكنك استخدامها كتبعيات في المشروع هي أيضًا، كل واحدة منها، صندوق واحد.

صناديق المكتبة

لقد قمنا بالفعل بتناول كيفية إنشاء برنامج ثنائي، وإنشاء مكتبة يكون بنفس السهولة. لإنشاء مكتبة، مرر معلمة --lib سطر الأوامر إلى cargo new الأمر :

$ cargo new --lib my-library
     Created library `my-library` package

يمكنك أن ترى أنه بدلا من src/main.rs ملف، يمكنك الآن الحصول على ملف =src/lib.rs.

my-library
├── src
│  └── lib.rs
└── Cargo.toml

عندما تخبر Cargo بتجميع هذا الصندوق، ستحصل على ملف مكتبة يسمى libmy_library.rlib يمكن نشره وربطه بمشاريع أخرى.

الوحدات

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

الوحدة النمطية هي مجموعة من العناصر:

  • الثوابت
  • الأسماء المستعارة للنوع
  • الدالات
  • البنيات
  • التعدادات
  • السمات
  • impl كتل
  • وحدات نمطية أخرى

تتحكم الوحدات أيضًا في خصوصية العنصر. تعرّف خصوصية العنصر أن العنصر إما عام وإما خاص. يعني العنصر العام أنه يمكن استخدامه من قِبَل التعليمات البرمجية الخارجية. يعني العنصر الخاص أن العنصر عبارة عن تفاصيل تنفيذ داخلية وأنه غير متاح للاستخدام الخارجي.

مثال حول وحدة نمطية:

mod math {
    type Complex = (f64, f64);
    pub fn sin(f: f64) -> f64 { /* ... */ }
    pub fn cos(f: f64) -> f64 { /* ... */ }
    pub fn tan(f: f64) -> f64 { /* ... */ }
}

println!("{}", math::cos(45.0));

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

ربما لاحظت pub الكلمة الأساسية في بداية تعريفات الدالة في الوحدة النمطية math .

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

// Declare a private struct
struct Foo;

// Declare a public struct with a private field
pub struct Bar {
    field: i32,
}

// Declare a public enum with two public variants
pub enum State {
    PubliclyAccessibleVariant,
    PubliclyAccessibleVariant2,
}

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