मॉड्यूल पाठ (2/2)
सन्दर्भ और उधार
रस्ट में, स्वामित्व को कार्यों में आगे-पीछे करना कठिन हो सकता है। इसे हल करने के लिए, रस्ट संदर्भ (&) का उपयोग करता है।
किसी मूल्य का संदर्भ बनाना उधार लेना कहलाता है।
अपरिवर्तनीय सन्दर्भ
& प्रतीक के साथ प्रकार या चर को उपसर्ग करके एक संदर्भ घोषित किया जाता है। डिफ़ॉल्ट रूप से, संदर्भ अपरिवर्तनीय होते हैं: वे मूल्य को पढ़ने की अनुमति देते हैं लेकिन इसे संशोधित नहीं करते हैं।
fn main() {
let s1 = String::from("hello");
// We pass a reference to s1, not ownership
let len = calculate_length(&s1);
// s1 is still usable here!
println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize { // s is a reference to a String
s.len()
} // Here, s goes out of scope, but since it doesn't own the value, nothing happensपरिवर्तनशील सन्दर्भ
यदि आपको उधार लिए गए मूल्य को संशोधित करने की आवश्यकता है, तो आपको &mut के साथ परिवर्तनीय संदर्भ का उपयोग करना होगा। मूल चर को mut के साथ परिवर्तनशील भी घोषित किया जाना चाहिए:
fn main() {
let mut s = String::from("hello");
// We pass a mutable reference
change(&mut s);
println!("{}", s); // Prints "hello, world"
}
fn change(some_string: &mut String) {
some_string.push_str(", world");
}उधार लेने के नियम
संकलन-समय पर स्मृति भ्रष्टाचार और डेटा दौड़ को रोकने के लिए, रस्ट दो मूलभूत नियम लागू करता है:
- आपके पास एक ही समय में किसी मान के लिए कितनी भी संख्या में अपरिवर्तनीय संदर्भ (
&T) हो सकते हैं। - या आपके पास एक समय में एक मूल्य के लिए बिल्कुल एक परिवर्तनशील संदर्भ (
&mut T) हो सकता है।
आप एक ही दायरे में एक ही मूल्य के लिए अपरिवर्तनीय और परिवर्तनशील संदर्भों को बिल्कुल नहीं मिला सकते हैं:
let mut s = String::from("hello");
let r1 = &s; // Valid
let r2 = &s; // Valid
// let r3 = &mut s; // COMPILATION ERROR! You cannot create &mut s if s is already borrowed as immutableरेफरेंस स्कोप और नॉन-लेक्सिकल लाइफटाइम्स (एनएलएल)
ऐतिहासिक रूप से, किसी संदर्भ का दायरा उस ब्लॉक के अंत तक रहता है जिसमें इसे बनाया गया था। आज, रस्ट का कंपाइलर नॉन-लेक्सिकल लाइफटाइम्स (एनएलएल) की बदौलत अधिक स्मार्ट हो गया है: एक संदर्भ का दायरा उस अंतिम पंक्ति पर समाप्त होता है जिसका वास्तव में उपयोग किया जाता है, जरूरी नहीं कि ब्लॉक के अंत में हो।
यह निम्नलिखित कोड को पूर्णतया वैध बनाता है:
let mut s = String::from("hello");
let r1 = &s;
let r2 = &s;
println!("{} and {}", r1, r2); // Last use of r1 and r2. The immutable references expire here!
let r3 = &mut s; // Valid! No active immutable references exist at this pointखुद कोशिश करना
& प्रतीक का उपयोग करके कैलकुलेट_लेंथ फ़ंक्शन में s1 का एक अपरिवर्तनीय संदर्भ पास करें।
संकेत दिखाएँ
स्ट्रिंग का अपरिवर्तनीय संदर्भ पास करने के लिए `/* TODO \_/``&s1` से बदलें।
3 प्रयासों के बाद समाधान उपलब्ध है
वेरिएबल s को म्यूटेबल बनाएं (let mut s) और स्ट्रिंग को संशोधित करने की अनुमति देने के लिए चेंज फ़ंक्शन में एक म्यूटेबल रेफरेंस (&mut s) पास करें।
संकेत दिखाएँ
'let s' के बजाय 'let mut s' का प्रयोग करें और 'change(&mut s);' को कॉल करें।
3 प्रयासों के बाद समाधान उपलब्ध है
Declare a variable s containing String::from("Rust"). Create two distinct immutable references r1 and r2 to s, and finally print both references separated by a space using the println! macro.
संकेत दिखाएँ
Assign `let r1 = &s;` and `let r2 = &s;` to obtain two immutable references, then print them with `println!("{} {}", r1, r2);`.
3 प्रयासों के बाद समाधान उपलब्ध है