Rust: फंक्शनल या OOP? सही स्टाइल चुनें बेहतरीन कोड के लिए

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

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

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

परिचय: एक भाषा में दो दुनियाएँ

\n\n

जब आप Rust सीखना शुरू करते हैं, तो आप जल्दी ही इसकी अनोखी स्थिति देखते हैं। यह भाषा आपको सोचने का एक ही तरीका नहीं थोपती। Java (जहाँ सब कुछ ऑब्जेक्ट है) या Haskell (जहाँ सब कुछ फंक्शन है) के विपरीत, Rust आपको चुनने की आज़ादी देता है। लेकिन इस आज़ादी के साथ ज़िम्मेदारी भी आती है: कौन सा दृष्टिकोण चुनें — फंक्शनल या ऑब्जेक्ट-ओरिएंटेड?

\n\n

Python या C++ की दुनिया से Rust में आने वाले कई डेवलपर्स सहज रूप से OOP (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) की ओर आकर्षित होते हैं। वे क्लासेस, इनहेरिटेंस और परिचित पैटर्न खोजते हैं। वहीं, Haskell या Scala की दुनिया से प्रेरित अन्य लोग, मोनाड, इम्यूटेबिलिटी और कम्पोज़ीशन का उपयोग करके केवल फंक्शनल स्टाइल में Rust लिखने की कोशिश करते हैं।

\n\n

सच्चाई, हमेशा की तरह, बीच में है। Rust एक मल्टी-पैराडाइम भाषा है जो आपको दोनों दुनियाओं का सर्वश्रेष्ठ लेने की अनुमति देती है। इस लेख में, हम जानेंगे कि Rust में फंक्शनल दृष्टिकोण का प्रभावी ढंग से उपयोग कैसे करें और कब ऑब्जेक्ट-ओरिएंटेड पैटर्न लागू करें। आप सीखेंगे कि ऐसा कोड कैसे लिखें जो न केवल काम करे बल्कि अपनी सुंदरता से मन मोह ले।

\n\n

Rust में OOP की बुनियाद: क्लासेस के बजाय ट्रेट्स

\n\n

चलिए सीधे बात करते हैं। Rust में क्लासिकल अर्थों में क्लासेस नहीं हैं। लेकिन इसका मतलब यह नहीं है कि आप OOP का उपयोग नहीं कर सकते। क्लासेस के बजाय यहाँ ट्रेट्स (traits) और स्ट्रक्चर्स (structs) का उपयोग किया जाता है। ये ही आपको एनकैप्सुलेशन, पॉलीमॉर्फिज्म और यहाँ तक कि इनहेरिटेंस जैसी सुविधाएँ प्रदान करते हैं।

\n\n

स्ट्रक्चर्स और मेथड्स

\n\n

स्ट्रक्चर्स आपके 'ऑब्जेक्ट' हैं। आप डेटा को परिभाषित करते हैं, और फिर impl की मदद से उनमें मेथड्स जोड़ते हैं:

\n\n
struct Player {\n    name: String,\n    health: i32,\n    level: u32,\n}\n\nimpl Player {\n    // कंस्ट्रक्टर मेथड\n    fn new(name: &str) -> Self {\n        Player {\n            name: name.to_string(),\n            health: 100,\n            level: 1,\n        }\n    }\n\n    // स्थिति बदलने वाला मेथड\n    fn take_damage(&mut self, damage: i32) {\n        self.health = (self.health - damage).max(0);\n    }\n\n    // गेटर (एक्सेस मेथड)\n    fn is_alive(&self) -> bool {\n        self.health > 0\n    }\n}\n
\n\n

यह शुद्ध OOP-शैली है: हमारे पास स्थिति (स्ट्रक्चर के फील्ड) और व्यवहार (मेथड्स) है। Rust विजिबिलिटी कंट्रोल (pub मॉडिफायर) के माध्यम से एनकैप्सुलेशन सुनिश्चित करता है।

\n\n

ट्रेट्स के माध्यम से पॉलीमॉर्फिज्म

\n\n

क्लास इनहेरिटेंस के बजाय, Rust ट्रेट्स के माध्यम से पॉलीमॉर्फिज्म का उपयोग करता है। यह क्लासिकल इनहेरिटेंस से अधिक शक्तिशाली और सुरक्षित है, क्योंकि आपको 'डायमंड प्रॉब्लम' या अनावश्यक व्यवहार विरासत में लेने जैसी समस्याओं का सामना नहीं करना पड़ता।

\n\n
trait Attackable {\n    fn attack(&self, target: &mut Player);\n}\n\nstruct Swordsman {\n    damage: i32,\n}\n\nimpl Attackable for Swordsman {\n    fn attack(&self, target: &mut Player) {\n        target.take_damage(self.damage);\n        println!("तलवारबाज ने {} नुकसान पहुँचाया!", self.damage);\n    }\n}\n\nstruct Mage {\n    spell_power: i32,\n    mana_cost: i32,\n}\n\nimpl Attackable for Mage {\n    fn attack(&self, target: &mut Player) {\n        target.take_damage(self.spell_power * 2);\n        println!("जादूगर ने {} शक्ति का फायरबॉल छोड़ा!", self.spell_power * 2);\n    }\n}\n
\n\n

अब आप किसी भी ऑब्जेक्ट के साथ काम कर सकते हैं जो Attackable ट्रेट को लागू करता है, बिना उसके विशिष्ट प्रकार की चिंता किए:

\n\n
fn perform_attack(attacker: &impl Attackable, target: &mut Player) {\n    attacker.attack(target);\n}\n
\n\n

इसे 'स्टेरॉयड पर डक टाइपिंग' या स्टैटिक पॉलीमॉर्फिज्म कहा जाता है। Rust सब कुछ कंपाइल टाइम पर जाँचता है, इसलिए आपको रनटाइम में कोई त्रुटि नहीं मिलेगी।

\n\n

फंक्शनल दृष्टिकोण: इटरेटर और क्लोजर

\n\n

अब स्विच करते हैं

ब्लॉग

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