रस्ट का मॉड्यूल सिस्टम वास्तव में अविश्वसनीय रूप से लचीला है और आपको यह जानने की अनुमति देगा कि आप अपने कोड को फ़ाइलों में किस तरह से संरचित करते हैं।
मुझे लगता है कि यहां कुंजी का उपयोग करना है pub use
, जो आपको अन्य मॉड्यूल से पहचानकर्ताओं को फिर से निर्यात करने की अनुमति देगा। रस्ट के std::io
टोकरे में इसके लिए मिसाल है, जहां उप-मॉड्यूल से कुछ प्रकार फिर से उपयोग के लिए निर्यात किएstd::io
जाते हैं ।
संपादित करें (2019-08-25): उत्तर के निम्नलिखित भाग को कुछ समय पहले लिखा गया था। यह बताता है कि इस तरह के एक मॉड्यूल संरचना को rustc
अकेले कैसे सेटअप किया जाए। आज, एक आमतौर पर अधिकांश उपयोग के मामलों के लिए कार्गो का उपयोग करेगा। हालांकि निम्नलिखित अभी भी मान्य है, इसके कुछ हिस्से (जैसे #![crate_type = ...]
) अजीब लग सकते हैं। यह अनुशंसित समाधान नहीं है।
अपने उदाहरण को अनुकूलित करने के लिए, हम इस निर्देशिका संरचना के साथ शुरुआत कर सकते हैं:
src/
lib.rs
vector.rs
main.rs
यहाँ आपका है main.rs
:
extern crate math;
use math::vector;
fn main() {
println!("{:?}", vector::VectorA::new());
println!("{:?}", vector::VectorB::new());
}
और आपका src/lib.rs
:
#[crate_id = "math"];
#[crate_type = "lib"];
pub mod vector; // exports the module defined in vector.rs
और अंत में src/vector.rs
:
// exports identifiers from private sub-modules in the current
// module namespace
pub use self::vector_a::VectorA;
pub use self::vector_b::VectorB;
mod vector_b; // private sub-module defined in vector_b.rs
mod vector_a { // private sub-module defined in place
#[derive(Debug)]
pub struct VectorA {
xs: Vec<i64>,
}
impl VectorA {
pub fn new() -> VectorA {
VectorA { xs: vec![] }
}
}
}
और यहीं से जादू होता है। हमने एक उप-मॉड्यूल को परिभाषित किया है math::vector::vector_a
जिसमें एक विशेष प्रकार के वेक्टर के कुछ कार्यान्वयन हैं। लेकिन हम नहीं चाहते हैं कि आपकी लाइब्रेरी के ग्राहक इस बात का ध्यान रखें कि vector_a
सब-मॉड्यूल हो। इसके बजाय, हम इसे math::vector
मॉड्यूल में उपलब्ध कराना चाहेंगे । इसके साथ किया जाता है pub use self::vector_a::VectorA
, जो vector_a::VectorA
वर्तमान मॉड्यूल में पहचानकर्ता को फिर से निर्यात करता है ।
लेकिन आपने पूछा कि यह कैसे करना है ताकि आप अपने विशेष वेक्टर कार्यान्वयन को विभिन्न फाइलों में डाल सकें। यह वही है जो mod vector_b;
लाइन करता है। यह रस्ट कंपाइलर को vector_b.rs
उस मॉड्यूल के कार्यान्वयन के लिए एक फ़ाइल देखने के लिए निर्देश देता है । और यकीन है कि यहाँ, हमारी src/vector_b.rs
फ़ाइल है:
#[derive(Debug)]
pub struct VectorB {
xs: Vec<i64>,
}
impl VectorB {
pub fn new() -> VectorB {
VectorB { xs: vec![] }
}
}
ग्राहक के दृष्टिकोण से, तथ्य यह है कि VectorA
और VectorB
दो अलग अलग फ़ाइलों में दो अलग-अलग मॉड्यूल में परिभाषित कर रहे हैं पूरी तरह से अपारदर्शी है।
यदि आप उसी निर्देशिका में हैं main.rs
, तो आपको इसे चलाने में सक्षम होना चाहिए:
rustc src/lib.rs
rustc -L . main.rs
./main
सामान्य तौर पर, रस्ट बुक में "क्रेट्स एंड मॉड्यूल्स" अध्याय बहुत अच्छा है। इसके बहुत सारे उदाहरण हैं।
अंत में, रस्ट कंपाइलर स्वचालित रूप से आपके लिए उप-निर्देशिकाओं में भी दिखता है। उदाहरण के लिए, उपरोक्त कोड इस निर्देशिका संरचना के साथ अपरिवर्तित काम करेगा:
src/
lib.rs
vector/
mod.rs
vector_b.rs
main.rs
संकलित करने और चलाने के आदेश समान रूप से बने रहते हैं।