Rust में self बनाम Self: शुरुआती और उन्नत के लिए पूर्ण गाइड

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

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

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

परिचय: एक छोटा अक्षर, बड़ा अंतर

\n\n

नमस्ते, भविष्य के Rust डेवलपर! यदि आपने Rust सीखना शुरू कर दिया है, तो आपने शायद देखा होगा कि कंपाइलर एक सख्त लेकिन निष्पक्ष शिक्षक है। यह टाइपो को माफ नहीं करता, और सिंटैक्स में भ्रम को तो बिल्कुल भी नहीं। सबसे आम जालों में से एक, जिसमें शुरुआती (और केवल वे ही नहीं) फंसते हैं, वह है self और Self के बीच भ्रम। ऐसा लगता है कि अंतर सिर्फ एक अक्षर का है - बड़ा या छोटा। लेकिन इस अक्षर के पीछे इंस्टेंस और प्रकार के बीच एक मूलभूत अंतर छिपा है।

\n\n

Stack Overflow पर इस प्रश्न को हज़ारों बार देखा गया है, और यह कोई संयोग नहीं है। आज हम एक बार और हमेशा के लिए समझ लेंगे कि Rust में self और Self में क्या अंतर है। हम केवल एक उबाऊ परिभाषा नहीं पढ़ेंगे, बल्कि जीवंत उदाहरणों के साथ एक चरण-दर-चरण ट्यूटोरियल से गुज़रेंगे, और कुछ छोटे प्रोग्राम लिखेंगे। लेख के अंत तक, आप न केवल अंतर जानेंगे, बल्कि इसे सहज स्तर पर महसूस करेंगे। चलिए शुरू करते हैं!

\n\n

1. self: "मैं" - यह इंस्टेंस के बारे में है

\n\n

चलिए self से शुरू करते हैं। Rust में, कई अन्य भाषाओं की तरह, self का उपयोग किसी स्ट्रक्चर या एनुम के वर्तमान इंस्टेंस को दर्शाने के लिए किया जाता है। यह C++, Java, JavaScript या Python में this के समान है। जब आप कोई ऐसा मेथड लिखते हैं जो किसी विशिष्ट ऑब्जेक्ट पर कॉल किया जाता है, तो आप self का उपयोग करते हैं।

\n\n

मेथड सिग्नेचर में self के तीन मुख्य रूप हैं:

\n
    \n
  • self — इंस्टेंस का स्वामित्व लेता है (consumes the instance)। मेथड कॉल करने के बाद मूल ऑब्जेक्ट अनुपलब्ध हो जाता है।
  • \n
  • &self — इंस्टेंस का अपरिवर्तनीय संदर्भ (सबसे सामान्य मामला)। मेथड डेटा पढ़ सकता है, लेकिन उसे बदल नहीं सकता।
  • \n
  • &mut self — इंस्टेंस का परिवर्तनीय संदर्भ। मेथड स्ट्रक्चर के फ़ील्ड को बदल सकता है।
  • \n
\n\n

आइए एक सरल उदाहरण लिखें। कल्पना करें कि हम एक छात्र स्ट्रक्चर बना रहे हैं।

\n\n
struct छात्र {\n    नाम: String,\n    कक्षा: u32,\n}\n\nimpl छात्र {\n    // मेथड जो &self (अपरिवर्तनीय संदर्भ) लेता है\n    fn परिचय_देना(&self) {\n        println!("नमस्ते! मैं {}, {} कक्षा में पढ़ता/पढ़ती हूँ।", self.नाम, self.कक्षा);\n    }\n\n    // मेथड जो &mut self (परिवर्तनीय संदर्भ) लेता है\n    fn अगली_कक्षा_में_जाना(&mut self) {\n        self.कक्षा += 1;\n        println!("{} अब {} कक्षा में है!", self.नाम, self.कक्षा);\n    }\n\n    // मेथड जो self (स्वामित्व) लेता है\n    fn पढ़ाई_पूरी_करना(self) {\n        println!("{} ने {} कक्षा में पढ़ाई पूरी की। अलविदा!", self.नाम, self.कक्षा);\n        // यहाँ self नष्ट हो जाता है, मेमोरी मुक्त हो जाती है\n    }\n}\n\nfn main() {\n    let mut छात्र1 = छात्र {\n        नाम: String::from("अन्ना"),\n        कक्षा: 2,\n    };\n\n    छात्र1.परिचय_देना(); // &self\n    छात्र1.अगली_कक्षा_में_जाना(); // &mut self\n    छात्र1.पढ़ाई_पूरी_करना(); // self (स्वामित्व)\n\n    // पढ़ाई_पूरी_करना कॉल करने के बाद, 'छात्र1' वेरिएबल अब उपलब्ध नहीं है!\n    // कंपाइलेशन त्रुटि देखने के लिए निम्नलिखित पंक्ति को अनकमेंट करें:\n    // छात्र1.परिचय_देना(); // त्रुटि: स्थानांतरित मान का उपयोग (borrow of moved value)\n}
\n\n

अंतिम टिप्पणी पर ध्यान दें। जब हम self (बिना संदर्भ के) पास करते हैं, तो हम स्वामित्व छोड़ देते हैं। यह एक शक्तिशाली उपकरण है जो ऑब्जेक्ट के जीवनकाल को सटीक रूप से नियंत्रित करने की अनुमति देता है। अन्य भाषाओं (जैसे, Python) में ऐसा कोई नियंत्रण नहीं है - ऑब्जेक्ट तब तक जीवित रहता है जब तक उस पर संदर्भ हैं। Rust में, आप स्वयं तय करते हैं कि ऑब्जेक्ट कब "भस्म" होगा।

\n\n

2. Self: "मैं" - यह प्रकार के बारे में है

\n\n

अब सबसे दिलचस्प बात। Self (बड़े अक्षर के साथ) उस प्रकार का उपनाम (alias) है जिसके लिए हम मेथड लागू कर रहे हैं। सीधे शब्दों में कहें तो, impl ब्लॉक के अंदर Self को उस स्ट्रक्चर या एनुम के नाम से बदल दिया जाता है जिसके साथ हम काम कर रहे हैं।

\n\n

इसकी आवश्यकता क्यों है? पहला, यह सुविधाजनक है। स्ट्रक्चर का पूरा नाम लिखने के बजाय, आप Self लिखते हैं। दूसरा, यह महत्वपूर्ण है क्योंकि

ब्लॉग

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