Rust: main.rs और lib.rs — मॉड्यूल में भ्रम से कैसे बचें और कोड को तेज़ कैसे करें

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Rust मॉड्यूल भ्रम: कैसे main.rs और lib.rs पागल कर देते हैं (और इसे कैसे ठीक करें)

\n\n

क्या आपने कभी Rust में लिखा है, एक नया प्रोजेक्ट बनाया है, main.rs और lib.rs जोड़ा है — और अचानक कंपाइलर ऐसी त्रुटियाँ दिखाने लगा है जो बेमानी लगती हैं? परिचित लगता है? यदि आपने "Rust modules confusion when there is main.rs and lib.rs" गूगल किया है, तो आप अकेले नहीं हैं। Stack Overflow पर इस प्रश्न ने हज़ारों बार देखा गया है, और यह सही भी है। मॉड्यूल के साथ भ्रम शुरुआती (और यहाँ तक कि अनुभवी डेवलपर्स के लिए भी जो अन्य भाषाओं से आते हैं) के लिए सबसे आम समस्याओं में से एक है।

\n\n

इस लेख में, हम केवल यह नहीं समझाएँगे कि Rust की मॉड्यूल प्रणाली कैसे काम करती है। हम दिखाएँगे कि इसका सही संगठन सीधे आपके कोड के अनुकूलन और प्रदर्शन को कैसे प्रभावित करता है। आप जानेंगे कि lib.rs केवल "एक और फ़ाइल" नहीं है, बल्कि संकलन को गति देने और एक स्वच्छ API बनाने के लिए एक शक्तिशाली उपकरण है। चलिए शुरू करते हैं!

\n\n

समस्या: "कंपाइलर मेरे मॉड्यूल क्यों नहीं देख रहा है?"

\n\n

कल्पना करें: आपने cargo new my_project का उपयोग करके एक प्रोजेक्ट my_project बनाया है। डिफ़ॉल्ट रूप से, Cargo src/main.rs बनाता है। आप एक दूसरी फ़ाइल — src/lib.rs — जोड़ते हैं और उसमें एक फ़ंक्शन लिखते हैं। फिर आप इसे main.rs से कॉल करने का प्रयास करते हैं — और आपको यह त्रुटि मिलती है:

\n\n
error[E0432]: unresolved import `my_project::some_function`\n --> src/main.rs:1:5\n  |\n1 | use my_project::some_function;\n  |     ^^^^^^^^^^^^^^^^^^^^^^^^^ no `some_function` in the root
\n\n

परिचित दर्द? मामला क्या है? यह सरल है: Rust main.rs और lib.rs को क्रेट के दो अलग-अलग रूट मानता है। यदि Cargo.toml में अन्यथा निर्दिष्ट नहीं किया गया है, तो Cargo स्वचालित रूप से दो क्रेट बनाता है: एक बाइनरी (main.rs से) और एक लाइब्रेरी (lib.rs से)। वे एक-दूसरे को सीधे "नहीं देखते" जब तक कि आप स्पष्ट रूप से निर्भरताएँ निर्दिष्ट नहीं करते।

\n\n

यह वही Rust मॉड्यूल भ्रम है जिसके बारे में हर कोई बात करता है। लेकिन नाराज़ होने के बजाय, आइए इस "विशेषता" को एक लाभ में बदल दें।

\n\n

समाधान: मॉड्यूल को सही तरीके से कैसे व्यवस्थित करें

\n\n

दो दृष्टिकोण हैं, और चुनाव आपके लक्ष्य पर निर्भर करता है। लेकिन हम तुरंत एक स्पॉइलर देते हैं: दूसरा दृष्टिकोण प्रदर्शन के लिए बेहतर है।

\n\n

विकल्प 1: सब कुछ एक ही क्रेट में (सरल, लेकिन स्केलेबल नहीं)

\n\n

यदि आपका प्रोजेक्ट छोटा है, तो आप main.rs के अंदर mod का उपयोग करके मॉड्यूल घोषित कर सकते हैं:

\n\n
// src/main.rs\nmod utils; // src/utils.rs या src/utils/mod.rs खोजता है\n\nfn main() {\n    utils::do_something();\n}
\n\n

यह काम करता है, लेकिन यदि आप lib.rs जोड़ते हैं, तो भ्रम शुरू हो जाता है। lib.rs एक अलग क्रेट बन जाएगा, और main.rs के मॉड्यूल इसमें उपलब्ध नहीं होंगे। छोटी स्क्रिप्ट के लिए ठीक है, गंभीर प्रोजेक्ट के लिए नहीं।

\n\n

विकल्प 2: लाइब्रेरी + बाइनरी (अनुकूलन के लिए सही रास्ता)

\n\n

सबसे समझदार तरीका है lib.rs को तर्क का मुख्य भंडार बनाना और main.rs को चलाने के लिए एक पतली आवरण बनाना। इस तरह आपको मिलता है:

\n
    \n
  • मॉड्यूलरिटी: सभी व्यावसायिक तर्क लाइब्रेरी में।
  • \n
  • परीक्षण क्षमता: लाइब्रेरी का अलग से परीक्षण किया जा सकता है।
  • \n
  • प्रदर्शन: यदि लाइब्रेरी कोड का बार-बार उपयोग किया जाता है तो कंपाइलर इसे बेहतर ढंग से अनुकूलित करता है।
  • \n
\n\n

यह कैसे करें? बस:

\n
// src/lib.rs\npub mod utils;\n\npub fn run() {\n    utils::do_something();\n}\n\n// src/main.rs\nfn main() {\n    my_project::run(); // my_project — Cargo.toml से क्रेट का नाम\n}
\n\n

ध्यान दें: main.rs अब my_project::run() का उपयोग करता है। यह काम करता है क्योंकि Cargo lib.rs को my_project नाम की लाइब्रेरी के रूप में देखता है। वोइला — भ्रम गायब हो गया!

\n\n

अनुकूलन और प्रदर्शन: क्यों lib.rs आपका मित्र है

\n\n

अब सबसे दिलचस्प बात

ब्लॉग

पुस्तक अनुशंसाएँ