एकाकी उद्धरण चिह्न के पीछे क्या छिपा है? Rust में lifetime से परिचय
\n\nयदि आपने कभी Rust कोड खोला है और &'a str या fn foo<'a>() जैसी अजीब संरचनाएँ देखी हैं, तो आपने निश्चित रूप से सोचा होगा: "ये एपॉस्ट्रॉफ़ी क्या हैं?" आप अकेले नहीं हैं - इस प्रश्न ने Stack Overflow पर हज़ारों बार देखा गया है और शुरुआती लोगों के लिए एक वास्तविक सिरदर्द बन गया है।
आज हम इन रहस्यमयी प्रतीकों को एक बार और हमेशा के लिए समझ लेंगे। स्पॉयलर: उद्धरण चिह्नों के पीछे Rust की सबसे शक्तिशाली अवधारणाओं में से एक छिपी है - जीवनकाल (lifetime)। और हाँ, यह उतना डरावना नहीं है जितना लगता है!
\n\nइस लेख में, मैं न केवल सिंटैक्स के बारे में बताऊंगा, बल्कि यह भी बताऊंगा कि एपॉस्ट्रॉफ़ी वाले पहचानकर्ताओं को सही तरीके से कैसे पढ़ें और उपयोग करें। चलिए शुरू करते हैं!
\n\nएपॉस्ट्रॉफ़ी के साथ पहचानकर्ता: केवल सजावट नहीं
\n\nRust में, एकल उद्धरण चिह्न से शुरू होने वाले पहचानकर्ता (जैसे 'a, 'static, 'b) जीवनकाल एनोटेशन हैं। वे इस बात को प्रभावित नहीं करते कि कोई वेरिएबल कितने समय तक जीवित रहता है, बल्कि केवल कंपाइलर को विभिन्न संदर्भों के जीवनकाल के बीच संबंधों के बारे में सूचित करते हैं।
कल्पना करें कि आप एक जासूस हैं, और Rust कंपाइलर आपका सहायक है। आप कहते हैं: "ये दो संदर्भ समान रूप से लंबे समय तक जीवित रहने चाहिए", और उन्हें 'a लेबल से चिह्नित करते हैं। कंपाइलर जाँचता है कि क्या आप इस नियम का उल्लंघन कर रहे हैं। यदि उल्लंघन करते हैं - तो आपको रनटाइम के बजाय कंपाइलेशन चरण में त्रुटि मिलती है।
वे ऐसे क्यों दिखते हैं?
\n\nएपॉस्ट्रॉफ़ी के साथ सिंटैक्स संयोग से नहीं चुना गया है। Rust में, एपॉस्ट्रॉफ़ी का उपयोग लेबल (labels) को दर्शाने के लिए किया जाता है - ये समय अंतरालों के लिए एक प्रकार के "नाम" हैं। यह दृष्टिकोण अन्य भाषाओं में भी पाया जाता है, लेकिन Rust में यह मेमोरी सुरक्षा प्रणाली का एक प्रमुख तत्व बन गया है।
\n\nयहाँ कुछ उदाहरण दिए गए हैं जहाँ आप ये लेबल देखेंगे:
\n\n- \n
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str- एक फ़ंक्शन जो एक संदर्भ लौटाता है जो दोनों तर्कों से अधिक समय तक जीवित नहीं रहता। \n struct Book<'a> { title: &'a str }- एक संरचना जिसमें जीवनकाल वाला संदर्भ होता है। \n &'static str- एक स्थिर स्ट्रिंग का संदर्भ जो पूरे प्रोग्राम के दौरान जीवित रहता है। \n
lifetime को कैसे पढ़ें और समझें?
\n\nआइए कुछ वास्तविक कोड उदाहरणों को समझें। वे आपको एपॉस्ट्रॉफ़ी से डरना बंद करने और उनका उपयोग शुरू करने में मदद करेंगे।
\n\nउदाहरण 1: एक जीवनकाल वाला फ़ंक्शन
\n\nमान लीजिए, हम एक फ़ंक्शन लिख रहे हैं जो दो स्ट्रिंग्स में से सबसे लंबी स्ट्रिंग लौटाता है:
\n\nfn longest<'a>(x: &'a str, y: &'a str) -> &'a str {\n if x.len() > y.len() { x } else { y }\n}\n\nfn main() {\n let string1 = String::from("hello");\n let result;\n {\n let string2 = String::from("world");\n result = longest(&string1, &string2);\n }\n // println!("{}", result); // कंपाइलेशन त्रुटि!\n}\n\nयहाँ क्या हो रहा है? हम कंपाइलर से कह रहे हैं: "परिणाम x और y दोनों से अधिक समय तक जीवित नहीं रहेगा"। जब string2 दायरे से बाहर हो जाता है, तो result अमान्य हो जाता है। कंपाइलर इसे देखता है और हमें खुद को नुकसान पहुँचाने से रोकता है।
उदाहरण 2: संदर्भ वाली संरचना
\n\nअक्सर शुरुआती लोग संरचनाओं में संदर्भ संग्रहीत करने का प्रयास करते हैं और त्रुटियाँ प्राप्त करते हैं। समाधान - स्पष्ट रूप से जीवनकाल निर्दिष्ट करना:
\n\n#[derive(Debug)]\nstruct Book<'a> {\n title: &'a str,\n author: &'a str,\n}\n\nfn main() {\n let title = String::from("The Rust Programming Language");\n let author = String::from("Steve Klabnik");\n let book = Book {\n title: &title,\n author: &author,\n };\n println!("{:?}", book);\n}\n\nयहाँ 'a का अर्थ है कि title और author को कम से कम उतने समय तक जीवित रहना चाहिए जितना स्वयं Book संरचना। यदि आप हटाने का प्रयास करते हैं