مقدمه

تاکنون تمام ماژول‌های خود را در داخل یک فایل واحد (src/lib.rs یا src/main.rs) تعریف کرده‌ایم. این روش برای پروژه‌های کوچک مناسب است، اما با رشد پروژه و بزرگتر شدن ماژول‌ها، نگه داشتن تمام کدها در یک فایل، خوانایی و قابلیت نگهداری آن را به شدت کاهش می‌دهد. Rust یک روش ساده و قدرتمند برای استخراج ماژول‌ها و قرار دادن آنها در فایل‌های مجزا ارائه می‌دهد که به ما کمک می‌کند تا ساختار پروژه را تمیز و سازماندهی شده نگه داریم.

استخراج ماژول‌ها به فایل‌های دیگر

قوانین استخراج ماژول در Rust بسیار ساده است. وقتی کامپایلر یک اعلان ماژول با فرمت mod my_module; را می‌بیند (که برخلاف mod my_module { ... } بدنه ندارد و با نقطه‌ویرگول تمام می‌شود)، به دنبال کد آن ماژول در مکان‌های زیر می‌گردد:

  • در فایلی به نام my_module.rs که در همان پوشه فایل فعلی قرار دارد.
  • در فایلی به نام my_module/mod.rs.

یک مثال عملی

بیایید مثال رستوران از درس‌های قبل را بازسازی کنیم. فرض کنید ساختار اولیه ما در src/lib.rs به شکل زیر است:

Copy Icon src/lib.rs
mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

pub use crate::front_of_house::hosting;

pub fn eat_at_restaurant() {
    hosting::add_to_waitlist();
}

حالا می‌خواهیم ماژول front_of_house را به فایل خودش منتقل کنیم. برای این کار، محتوای فایل src/lib.rs را به شکل زیر تغییر می‌دهیم:

Copy Icon src/lib.rs
// Declare the front_of_house module. Rust will look for its content
// in a file named `src/front_of_house.rs`.
mod front_of_house;

pub use crate::front_of_house::hosting;

pub fn eat_at_restaurant() {
    hosting::add_to_waitlist();
}

سپس، یک فایل جدید به نام src/front_of_house.rs ساخته و محتوای ماژول front_of_house را در آن قرار می‌دهیم:

Copy Icon src/front_of_house.rs
// All content that was inside the `front_of_house` module goes here.
pub mod hosting {
    pub fn add_to_waitlist() {}
}

با این کار، رفتار برنامه دقیقاً مانند قبل خواهد بود، اما کد ما اکنون در دو فایل مجزا سازماندهی شده و خواناتر است.

جداسازی ماژول‌های تودرتو

حالا اگر بخواهیم ماژول hosting را نیز به فایل خودش منتقل کنیم چه؟ ما باید از روش دوم که کامپایلر پشتیبانی می‌کند استفاده کنیم. یعنی یک پوشه جدید بسازیم.

  1. محتوای فایل src/front_of_house.rs را به src/front_of_house/mod.rs منتقل می‌کنیم.
  2. درون فایل src/front_of_house/mod.rs، اعلان ماژول hosting را به mod hosting; تغییر می‌دهیم.
  3. یک فایل جدید به نام src/front_of_house/hosting.rs ساخته و محتوای ماژول hosting را در آن قرار می‌دهیم.

پس از این تغییرات، ساختار فایل‌های پروژه به شکل زیر خواهد بود:

src/
├── lib.rs
└── front_of_house/
    ├── mod.rs
    └── hosting.rs
                    

و محتوای فایل‌ها به این صورت خواهد بود:

Copy Icon src/front_of_house/mod.rs
pub mod hosting;
Copy Icon src/front_of_house/hosting.rs
pub fn add_to_waitlist() {}

این الگو به صورت بازگشتی قابل تکرار است و به ما اجازه می‌دهد تا پیچیده‌ترین پروژه‌ها را به صورت یک ساختار فایل و پوشه تمیز و قابل مدیریت سازماندهی کنیم.

در این درس یاد گرفتیم که چگونه با استخراج ماژول‌ها به فایل‌های مجزا، ساختار پروژه خود را مقیاس‌پذیر و قابل نگهداری کنیم. با این درس، فصل «مدیریت پروژه با پکیج‌ها و ماژول‌ها» به پایان می‌رسد. ما در این فصل با واحدهای کامپایل (Crate)، بسته‌بندی (Package) و سازماندهی کد (Module) آشنا شدیم و اکنون ابزارهای لازم برای ساخت پروژه‌های بزرگ و پیچیده در Rust را در اختیار داریم. در فصل بعدی، به سراغ یکی از مهم‌ترین بخش‌های هر زبان برنامه‌نویسی، یعنی «کالکشن‌ها» خواهیم رفت و با انواع داده‌ای پرکاربردی مانند Vec، String و HashMap آشنا می‌شویم.