गैर-शाब्दिक जीवनकाल क्या हैं?


87

रस्ट में गैर-शाब्दिक जीवनकाल से संबंधित एक आरएफसी है जिसे लंबे समय तक भाषा में लागू करने की मंजूरी दी गई हैहाल ही में , रस्ट के इस फीचर के समर्थन में बहुत सुधार हुआ है और इसे पूर्ण माना गया है।

मेरा सवाल है: वास्तव में एक गैर-शाब्दिक जीवनकाल क्या है?

जवाबों:


130

यह समझने में सबसे आसान है कि गैर-शाब्दिक जीवनकाल क्या हैं, यह समझने के द्वारा कि क्या शाब्दिक जीवनकाल हैं। गैर-शाब्दिक जीवनकाल मौजूद होने से पहले जंग के संस्करणों में, यह कोड विफल हो जाएगा:

fn main() {
    let mut scores = vec![1, 2, 3];
    let score = &scores[0];
    scores.push(4);
}

जंग संकलक देखता है कि चर scoresद्वारा उधार लिया गया है score, इसलिए यह आगे के परिवर्तन को अस्वीकार करता है scores:

error[E0502]: cannot borrow `scores` as mutable because it is also borrowed as immutable
 --> src/main.rs:4:5
  |
3 |     let score = &scores[0];
  |                  ------ immutable borrow occurs here
4 |     scores.push(4);
  |     ^^^^^^ mutable borrow occurs here
5 | }
  | - immutable borrow ends here

हालांकि, एक मानव तुच्छता से देख सकते हैं कि इस उदाहरण बहुत ज्यादा रूढ़िवादी है: scoreहै इस्तेमाल कभी नहीं किया ! समस्या यह है कि के उधार है scoresसे scoreहै शाब्दिक - यह ब्लॉक जिसमें यह निहित है के अंत तक रहता है:

fn main() {
    let mut scores = vec![1, 2, 3]; //
    let score = &scores[0];         //
    scores.push(4);                 //
                                    // <-- score stops borrowing here
}

गैर-शाब्दिक जीवनकाल इस स्तर को विस्तार से समझने के लिए संकलक को बढ़ाकर इसे ठीक करते हैं। कंपाइलर अब अधिक सटीक रूप से बता सकता है कि कब उधार की जरूरत है और यह कोड संकलित करेगा।

गैर-शाब्दिक जीवनकाल के बारे में एक अद्भुत बात यह है कि एक बार सक्षम होने के बाद, कोई भी उनके बारे में कभी नहीं सोचेगा । यह बस "रस्ट क्या करता है" बन जाएगा और चीजें (उम्मीद) बस काम करेंगी।

लेक्सिकल लाइफटाइम की अनुमति क्यों दी गई?

जंग का उद्देश्य केवल ज्ञात-सुरक्षित कार्यक्रमों को संकलित करने की अनुमति देना है। हालांकि, केवल सुरक्षित कार्यक्रमों की अनुमति देना और असुरक्षित लोगों को अस्वीकार करना असंभव है। उस अंत तक, रूस्ट रूढ़िवादी होने के पक्ष में गलतियां करता है: कुछ सुरक्षित कार्यक्रमों को अस्वीकार कर दिया जाता है। लेक्सिकल जीवनकाल इसका एक उदाहरण है।

संकलक में लेक्सिकल जीवनकाल को लागू करना बहुत आसान था क्योंकि ब्लॉक का ज्ञान "तुच्छ" है, जबकि डेटा प्रवाह का ज्ञान कम है। संकलक को "मध्य-स्तरीय मध्यवर्ती प्रतिनिधित्व" (एमआईआर) का परिचय और उपयोग करने के लिए फिर से लिखना आवश्यक है । तब उधार लेने वाले चेकर (उर्फ "उधार") को सार सिंटैक्स ट्री (एएसटी) के बजाय एमआईआर का उपयोग करने के लिए फिर से लिखना पड़ा। फिर उधार लेने वाले के नियमों को बारीक करने के लिए परिष्कृत किया जाना था।

लेक्सिकल लाइफटाइम हमेशा प्रोग्रामर के रास्ते में नहीं आते हैं, और लेक्सिकल लाइफटाइम के आसपास काम करने के कई तरीके होते हैं, भले ही वे कष्टप्रद हों। कई मामलों में, इसमें अतिरिक्त घुंघराले ब्रेस या बूलियन मूल्य शामिल होते हैं। इसने रस्ट 1.0 को जहाज करने की अनुमति दी और गैर-शाब्दिक जीवनकाल लागू होने से पहले कई वर्षों तक उपयोगी रहा।

दिलचस्प है, लेक्सिकल जीवनकाल के कारण कुछ अच्छे पैटर्न विकसित किए गए थे। मेरे लिए प्रमुख उदाहरण है पैटर्न । यह कोड गैर-शाब्दिक जीवनकाल से पहले विफल हो जाता है और इसके साथ संकलित करता है:entry

fn example(mut map: HashMap<i32, i32>, key: i32) {
    match map.get_mut(&key) {
        Some(value) => *value += 1,
        None => {
            map.insert(key, 1);
        }
    }
}

हालाँकि, यह कोड अक्षम है क्योंकि यह दो बार कुंजी के हैश की गणना करता है। यह समाधान जो लेक्सिकल जीवनकाल के कारण बनाया गया था वह छोटा और अधिक कुशल है:

fn example(mut map: HashMap<i32, i32>, key: i32) {
    *map.entry(key).or_insert(0) += 1;
}

नाम "गैर-शाब्दिक जीवनकाल" मेरे लिए सही नहीं लगता है

एक मूल्य का जीवनकाल वह समय अवधि है, जिसके दौरान मान एक विशिष्ट मेमोरी पते पर रहता है (देखें कि मैं उसी मूल्य को उसी संरचना में मान और स्टोर नहीं कर सकता हूं? एक लंबे स्पष्टीकरण के लिए)। गैर-शाब्दिक जीवनकाल के रूप में जाना जाने वाला फीचर किसी भी मूल्य के जीवनकाल को नहीं बदलता है, इसलिए यह जीवन रेखा को गैर-शाब्दिक नहीं बना सकता है। यह केवल उन मूल्यों के उधार की ट्रैकिंग और जाँच को अधिक सटीक बनाता है।

सुविधा के लिए एक अधिक सटीक नाम "गैर-शाब्दिक उधार " हो सकता है । कुछ संकलक डेवलपर्स अंतर्निहित "एमआईआर-आधारित उधार" को संदर्भित करते हैं।

गैर-शाब्दिक जीवन का उद्देश्य कभी भी "उपयोगकर्ता-सामना" सुविधा नहीं था, प्रति से । वे ज्यादातर हमारे दिमाग में बड़े हो गए हैं क्योंकि उनकी अनुपस्थिति से प्राप्त होने वाले छोटे कागज़ात के कारण। उनका नाम ज्यादातर आंतरिक विकास उद्देश्यों के लिए था और विपणन उद्देश्यों के लिए इसे बदलना कभी प्राथमिकता नहीं थी।

हाँ, लेकिन मैं इसका उपयोग कैसे करूँ?

1.31 रुस्ट (2018-12-06 को जारी) में, आपको अपने कार्गो में Rust 2018 संस्करण को ऑप्ट-इन करना होगा:

[package]
name = "foo"
version = "0.0.1"
authors = ["An Devloper <an.devloper@example.com>"]
edition = "2018"

1.36 रस्ट के रूप में, रस्ट 2015 संस्करण गैर-शाब्दिक जीवनकाल को भी सक्षम बनाता है।

गैर-शाब्दिक जीवनकाल का वर्तमान कार्यान्वयन "माइग्रेशन मोड" में है। यदि NLL उधार चेकर गुजरता है, तो संकलन जारी रहता है। यदि ऐसा नहीं होता है, तो पिछले उधार चेकर को आमंत्रित किया जाता है। यदि पुराना उधार लेने वाला चेकर कोड को अनुमति देता है, तो एक चेतावनी मुद्रित की जाती है, जो आपको सूचित करती है कि आपका कोड रस्ट के भविष्य के संस्करण में टूटने की संभावना है और इसे अपडेट किया जाना चाहिए।

रास्ट के रात्रिकालीन संस्करणों में, आप एक फीचर फ्लैग के माध्यम से लागू टूटने का विकल्प चुन सकते हैं:

#![feature(nll)]

आप संकलक झंडे का उपयोग करके एनएलएल के प्रयोगात्मक संस्करण के लिए ऑप्ट-इन भी कर सकते हैं -Z polonius

गैर-शाब्दिक जीवनकाल द्वारा हल की गई वास्तविक समस्याओं का एक नमूना


11
मुझे लगता है कि यह इस बात पर जोर देने के लायक होगा कि, शायद प्रति-सहज रूप से, नॉन-लेक्सिकल लाइफ़टाइम वैरिएबल के लाइफटाइम के बारे में नहीं हैं, बल्कि लाइफटाइम ऑफ बॉरो के बारे में हैं। या, अन्यथा कहा, नॉन-लेक्सिकल लाइफटाइम्स चर के जीवनकाल को उधार से सजाने के बारे में है ... जब तक मैं गलत नहीं हूं? (लेकिन मुझे नहीं लगता कि एनएलएल तब बदलता है जब किसी विध्वंसक को अंजाम दिया जाता है)
मैथ्यू एम।

2
" दिलचस्प है, लेक्सिकल लाइफटाइम के कारण कुछ अच्छे पैटर्न विकसित हुए थे " - मान लीजिए, तो, एक जोखिम है कि एनएलएल का अस्तित्व भविष्य के अच्छे पैटर्न बना सकता है जो पहचानने के लिए बहुत कठिन है?
१६

1
@eggyal यह निश्चित रूप से एक संभावना है। बाधाओं के एक सेट के भीतर डिजाइन करना (भले ही मनमाना!) नए, दिलचस्प डिजाइनों को जन्म दे सकता है। उन बाधाओं के बिना, हम अपने मौजूदा ज्ञान और पैटर्न पर वापस आ सकते हैं और कुछ नया खोजने या जानने के लिए कभी नहीं सीख सकते हैं। कहा जा रहा है, शायद किसी को लगता है कि "ओह, हैश की गणना दो बार की जा रही है, मैं इसे ठीक कर सकता हूं" और एपीआई बनाया जाएगा, लेकिन उपयोगकर्ताओं के लिए पहले स्थान पर एपीआई खोजना मुश्किल हो सकता है। मुझे उम्मीद है कि क्लिपी जैसे उपकरण उन लोगों की मदद करते हैं।
शमपास्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.