عندما يصبح الملف الواحد ضيقًا جدًا
\n\nأنت تكتب بلغة Rust. مشروعك ينمو. بالأمس فقط كان main.rs يحتوي على كل شيء - الدوال، الهياكل، وبعض الإعدادات. واليوم تقضي خمس دقائق للعثور على دالة معينة بين آلاف الأسطر. هل هذا مألوف؟
عاجلاً أم آجلاً، يواجه كل مطور Rust الحاجة إلى تقسيم الكود إلى أجزاء منطقية. قد يبدو الأمر بسيطًا؟ أنشئ مجلدًا، وزع الملفات، واستوردها - وانتهى الأمر. لكن نظام الوحدات النمطية في Rust يشتهر بصرامته. خطأ واحد في mod.rs - ويصدر المترجم خطأً ستقضي نصف ساعة في حله.
في هذه المقالة، سنستعرض أهم الأخطاء عند تقسيم وحدة Rust النمطية إلى عدة ملفات والأهم من ذلك، سنوضح كيفية تجنبها. ستتعلم كيفية تنظيم هيكل الملفات بشكل صحيح، ومتى تستخدم mod.rs، ومتى تستخدم lib.rs، ولماذا pub use هو أفضل صديق لك.
تشريح نظام الوحدات النمطية في Rust
\n\nقبل الغوص في الأخطاء، دعنا نستعرض الأساسيات. في Rust، الوحدة النمطية هي وحدة تنظيم الكود. افتراضيًا، كل ملف هو وحدة نمطية، لكن الأمور ليست بهذه البساطة.
\n\nهناك طريقتان:
\n\n- \n
- ملف-وحدة نمطية بنفس الاسم: الملف
utils.rsيصبح تلقائيًا الوحدة النمطيةutilsإذا قمت بتعريفmod utils;فيlib.rsأوmain.rs. \n - مجلد-وحدة نمطية: المجلد
utils/مع ملفmod.rsبداخله. في هذه الحالة،mod.rsهو نقطة الدخول إلى الوحدة النمطية. \n
يبدو الأمر بسيطًا، لكن هنا تكمن معظم المشاكل. دعنا نستعرض أكثرها شيوعًا.
\n\nأهم 5 أخطاء عند تقسيم الوحدة النمطية إلى عدة ملفات
\n\nالخطأ رقم 1: نسيان تعريف الوحدة الفرعية
\n\nقمت بإنشاء ملف network/tcp.rs وتحاول استخدامه. تكتب use network::tcp; - وتحصل على خطأ في الترجمة. لماذا؟ لأن Rust لا يفحص المجلدات تلقائيًا. يجب عليك تعريف كل وحدة فرعية بشكل صريح.
// network/mod.rs\n// ❌ خطأ: الوحدة الفرعية tcp غير معرفة\n// use network::tcp; // لن يتم ترجمتها\n\n// ✅ صحيح:\npub mod tcp; // تعريف الوحدة الفرعية\n\n\nكيفية تجنبه: تأكد دائمًا من إضافة pub mod اسم_الوحدة_الفرعية; في الوحدة النمطية الأم. هذا يشبه الاستيراد الصريح - Rust يتطلب الوضوح.
الخطأ رقم 2: الخلط بين mod.rs و lib.rs
\n\nغالبًا ما يضع المبتدئون mod.rs في جذر المشروع بجانب main.rs. هذا يعمل، ولكن فقط إذا كنت تنشئ مكتبة. بالنسبة للملف القابل للتنفيذ (main.rs)، الوحدة النمطية الجذرية هي main.rs نفسه. أما mod.rs فهو ملف داخل مجلد.
my_project/\n├── main.rs // الوحدة النمطية الجذرية للملف الثنائي\n├── lib.rs // الوحدة النمطية الجذرية للمكتبة (إن وجدت)\n├── utils/\n│ ├── mod.rs // نقطة الدخول إلى الوحدة النمطية utils\n│ └── helpers.rs\n\n\nكيفية تجنبه: تذكر القاعدة: mod.rs يعيش فقط داخل مجلد-وحدة نمطية. إذا كنت بحاجة إلى وحدة نمطية جذرية للمكتبة - استخدم lib.rs.
الخطأ رقم 3: نسيان pub في الوحدات الفرعية
\n\nقمت بتعريف الوحدة الفرعية، لكنك لا تزال غير قادر على استدعاء الدالة. على الأرجح، نسيت تحديد pub.
// network/mod.rs\npub mod tcp;\n\n// network/tcp.rs\n// ❌ الدالة خاصة افتراضيًا\nfn connect() { /* ... */ }\n\n// ✅ جعلها عامة\npub fn connect() { /* ... */ }\n\n\nفي Rust، كل شيء خاص افتراضيًا. هذا ليس خطأ، بل ميزة: أنت تقرر ما تفتحه للعالم الخارجي. إذا كانت الدالة مطلوبة خارج الوحدة النمطية - أضف pub.
كيفية تجنبه: استخدم pub بوعي. للأدوات الداخلية، اترك الوصول خاصًا. لواجهات API، اجعلها عامة.