Rust में मेटाप्रोग्रामिंग: मैक्रोज़ और कोड की नई शक्ति

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

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

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

परिचय: Rust कोड के साथ जादू क्यों कर सकता है?

\n\n

क्या आपने कभी Rust में कोड लिखते हुए महसूस किया है कि आप दर्जनों स्ट्रक्चर के लिए एक ही कोड को बार-बार लिख रहे हैं? या आप चाहते हैं कि ट्रेट का इम्प्लीमेंटेशन अपने आप जनरेट हो जाए, बिना मैन्युअली कोड कॉपी किए? आपका स्वागत है Rust में मेटाप्रोग्रामिंग की दुनिया में — ये वो तकनीकें हैं जो आपको ऐसा कोड लिखने देती हैं जो कोड लिखता है।

\n\n

Rust में रनटाइम पर पूर्ण रिफ्लेक्शन (जैसे Java या Python में) नहीं है, लेकिन यह उससे कहीं अधिक शक्तिशाली और सुरक्षित चीज़ प्रदान करता है — मैक्रोज़। ये कंपाइलेशन के समय काम करते हैं, एब्सट्रैक्ट सिंटैक्स ट्री (AST) का विश्लेषण और रूपांतरण करते हैं। यह बिना परफॉरमेंस खोए बॉयलरप्लेट कोड को कम करने और ऑप्टिमाइज़ करने की अविश्वसनीय क्षमता देता है।

\n\n

इस लेख में, हम मेटाप्रोग्रामिंग की उन्नत तकनीकों को समझेंगे: क्लासिक macro_rules! से लेकर पूर्ण प्रोसीजरल मैक्रोज़ तक। आप सीखेंगे कि अपने खुद के derive एट्रीब्यूट कैसे बनाएं और एट्रीब्यूट मैक्रोज़ कैसे लिखें जो कोड के अर्थ को बदल देते हैं। चलिए शुरू करते हैं!

\n\n

डिक्लेरेटिव मैक्रोज़: macro_rules! — सिर्फ "टेक्स्ट रिप्लेसमेंट" नहीं

\n\n

बहुत से लोग सोचते हैं कि macro_rules! एक आदिम टेक्स्ट प्रीप्रोसेसर है। वास्तव में, यह टोकन स्तर पर काम करने वाली एक शक्तिशाली पैटर्न मैचिंग प्रणाली है। यह आपको Rust के अंदर ही DSL (डोमेन-स्पेसिफिक लैंग्वेज) बनाने की अनुमति देती है।

\n\n

उन्नत उदाहरण: मैक्रो के साथ बिल्डर बनाना

\n\n

कल्पना करें कि आपको एक स्ट्रक्चर के लिए "बिल्डर" बनाना है। दर्जनों मेथड लिखने के बजाय, आप एक मैक्रो लिख सकते हैं:

\n\n
macro_rules! builder {\n    ($struct_name:ident, { $($field:ident: $field_type:ty),* $(,)? }) => {\n        struct $struct_name {\n            $($field: Option<$field_type>),*\n        }\n\n        impl $struct_name {\n            $(\n                pub fn $field(mut self, value: $field_type) -> Self {\n                    self.$field = Some(value);\n                    self\n                }\n            )*\n\n            pub fn build(self) -> Result<Self, String> {\n                $(\n                    if self.$field.is_none() {\n                        return Err(format!("फ़ील्ड {} आवश्यक है", stringify!($field)));\n                    }\n                )*\n                Ok(self)\n            }\n        }\n    };\n}\n\nbuilder!(Config, {\n    host: String,\n    port: u16,\n    timeout: u64,\n});\n\nfn main() {\n    let config = Config {\n        host: None,\n        port: None,\n        timeout: None,\n    }\n    .host("localhost".to_string())\n    .port(8080)\n    .build()\n    .unwrap();\n    println!("Config तैयार: {}:{}", config.host.unwrap(), config.port.unwrap());\n}\n
\n\n

यह मैक्रो सिर्फ फ़ील्ड जनरेट नहीं करता, बल्कि आवश्यक फ़ील्ड की वैलिडेशन भी जोड़ता है। ध्यान दें stringify!($field) पर — यह कंपाइलेशन के समय आइडेंटिफ़ायर को स्ट्रिंग में बदल देता है। यह Rust में उन्नत मेटाप्रोग्रामिंग की एक विशिष्ट तकनीक है।

\n\n

दोहराव और पैटर्न: $(...)* का उपयोग

\n\n

दोहराव सिंटैक्स आपको किसी भी लंबाई के आर्गुमेंट की सूची को प्रोसेस करने देता है। ident, ty, expr और अन्य "फ्रैगमेंट्स" को मिलाकर, आप जटिल पैटर्न बना सकते हैं। उदाहरण के लिए, Display के ऑटोमैटिक इम्प्लीमेंटेशन के साथ enum बनाने का मैक्रो:

\n\n
macro_rules! display_enum {\n    ($enum_name:ident, { $($variant:ident => $desc:expr),* $(,)? }) => {\n        enum $enum_name {\n            $($variant),*\n        }\n\n        impl std::fmt::Display for $enum_name {\n            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n                match self {\n                    $(Self::$variant => write!(f, "{}", $desc)),*\n                }\n            }\n        }\n    };\n}\n\ndisplay_enum!(Status, {\n    Active => "status_active",\n    Inactive => "status_inactive",\n    Pending => "s                

ब्लॉग

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