extern crate مقابل use في Rust: الفرق والاستخدام الصحيح

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

extern crate و use في Rust: الفرق الحقيقي وكيف تتجنب الأخطاء

\n\n

إذا كنت قد كتبت أي سطر من كود Rust من قبل، فبالتأكيد صادفت التعابير extern crate و use. للوهلة الأولى، قد يبدو أنهما يقومان بنفس المهمة — استيراد كود خارجي. لكن الفرق، كما هو الحال دائمًا، يكمن في التفاصيل. هذا السؤال من أكثر الأسئلة شيوعًا على Stack Overflow (آلاف المشاهدات!)، والمبتدئون يخلطون بينهما باستمرار. دعنا نوضح الفرق بين extern crate و use مرة واحدة وإلى الأبد، وأين يحدث السحر، وكيف تتجنب الأخطاء النمطية.

\n\n

باختصار: ما هو كل منهما

\n\n

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

\n\n

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

\n\n

ببساطة: extern crate يجيب على السؤال "ما الذي يمكننا استخدامه بشكل عام؟"، بينما use يجيب على "كيف يمكننا الوصول إليه بسهولة؟".

\n\n

السياق التاريخي: لماذا يحدث الخلط

\n\n

الخلط لم يحدث من فراغ. في الإصدارات القديمة من Rust (قبل 2018 edition)، كان extern crate إلزاميًا لأي crate خارجي. كان الأمر يبدو هكذا:

\n\n
// Rust 2015 — الطريقة القديمة\nextern crate serde;\nuse serde::{Serialize, Deserialize};
\n\n

ابتداءً من Rust 2018 edition، أصبح المُجمّع قادرًا على العثور على التبعيات من Cargo.toml بنفسه. الآن، لم يعد من الضروري كتابة extern crate لمعظم الـ crates. يكفي فقط إضافة التبعية في Cargo.toml واستخدام use مباشرة:

\n\n
// Rust 2018+ — الطريقة الجديدة (extern crate غير إلزامي)\nuse serde::{Serialize, Deserialize};
\n\n

هنا يبدأ العذاب للمبتدئين. يرون أمثلة قديمة حيث يُستخدم extern crate، وأمثلة جديدة بدونه، ويحاولون فهم متى يكون ضروريًا. تحذير: ضروري، ولكن في حالات نادرة جدًا.

\n\n

متى لا يزال extern crate ضروريًا (وهذا مهم!)

\n\n

هناك ثلاث حالات لا يمكنك فيها الاستغناء عن extern crate:

\n\n
    \n
  • الربط مع المكتبات النظامية عبر #[link] — إذا كنت تكتب روابط لكود C/C++ وتستخدم الخاصية #[link(name = "sqlite3")]، فإن extern crate إلزامي.
  • \n
  • الماكروات العامة (Global macros) — بعض الـ crates (مثل log) تُصدر ماكروات يجب أن تكون مرئية في جميع أنحاء البرنامج. في Rust 2018، تحتاج لكتابة extern crate log; لهذا الغرض.
  • \n
  • البناء بأسماء crates غير قياسية — إذا كنت تستخدم extern crate my_crate as foo; لإعادة تسمية الـ crate.
  • \n
\n\n

في جميع الحالات الأخرى، extern crate هو مجرد أثر من الماضي. لكن العديد من المطورين ما زالوا يكتبونه بدافع العادة، والمبتدئون ينسخون الكود من الدروس القديمة.

\n\n

أهم 5 أخطاء عند العمل مع extern crate و use

\n\n

الخطأ رقم 1: استخدام extern crate حيث لا داعي له

\n\n

المشكلة الأكثر شيوعًا. تضيف crate إلى Cargo.toml، ثم تكتب extern crate rand; — والكود يعمل. لكن هذا سطر زائد. في المشاريع الحديثة (Rust 2018+)، هو فقط يلوّث الكود وقد يربك المطورين الآخرين.

\n\n
// سيء (زائد عن الحاجة في Rust 2018+)\nextern crate rand;\nuse rand::Rng;

المدونات

توصيات الكتب