مرکزی مواد پر جائیں
ماڈیول 3 · سبق 2 از 2کورس میں 6/14~15 min
ماڈیول اسباق (2/2)

حوالہ جات اور قرض لینا

زنگ میں، ملکیت کو فنکشنز کو آگے پیچھے کرنا تکلیف دہ ہو سکتا ہے۔ اسے حل کرنے کے لیے، Rust حوالہ جات (&) استعمال کرتا ہے۔

کسی قدر کا حوالہ بنانا قرض لینا کہلاتا ہے۔

ناقابل تغیر حوالہ جات

قسم یا متغیر کو & علامت کے ساتھ سابقہ ​​لگا کر حوالہ کا اعلان کیا جاتا ہے۔ پہلے سے طے شدہ طور پر، حوالہ جات غیر متغیر ہوتے ہیں: وہ قدر کو پڑھنے کی اجازت دیتے ہیں لیکن اس میں ترمیم نہیں کرتے۔

Rust
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 کے ساتھ متغیر قرار دیا جانا چاہیے:

Rust
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");
}

قرض لینے کے احکام

کمپائل ٹائم میں میموری کی بدعنوانی اور ڈیٹا ریس کو روکنے کے لیے، Rust دو بنیادی اصول نافذ کرتا ہے:

  1. آپ کے پاس ایک ہی وقت میں کسی قدر کے لیے بہت سے متغیر حوالہ جات (&T) ہوسکتے ہیں۔
  2. یا آپ کے پاس ایک وقت میں ایک قدر کے لیے بالکل ایک تغیر پذیر حوالہ (&mut T) ہوسکتا ہے۔

آپ بالکل ایک ہی دائرہ کار میں ایک ہی قدر کے لیے ناقابل تغیر اور تغیر پذیر حوالہ جات کو ملا نہیں سکتے:

Rust
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

حوالہ دائرہ کار اور غیر لغوی لائف ٹائم (NLL)

تاریخی طور پر، ایک حوالہ کا دائرہ اس بلاک کے اختتام تک رہتا ہے جس میں اسے بنایا گیا تھا۔ آج، رسٹ کا کمپائلر Non-Lexical Lifetimes (NLL) کی بدولت زیادہ ہوشیار ہے: ایک حوالہ کا دائرہ اس آخری سطر پر ختم ہوتا ہے جو دراصل استعمال ہوتا ہے، ضروری نہیں کہ بلاک کے آخر میں ہو۔

یہ مندرجہ ذیل کوڈ کو بالکل درست بناتا ہے:

Rust
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

خود ہی آزمائیں۔

ورزش#rust.m3.l2.e1
کوششیں: 0لوڈ ہو رہا ہے…

& علامت کا استعمال کرتے ہوئے calculate_length فنکشن میں s1 کا ایک ناقابل تغیر حوالہ پاس کریں۔

ایڈیٹر لوڈ ہو رہا ہے…
اشارہ دکھائیں۔

سٹرنگ کا ایک ناقابل تغیر حوالہ منتقل کرنے کے لیے `/* TODO \_/`with`&s1` کو تبدیل کریں۔

3 کوششوں کے بعد حل دستیاب ہے۔

ورزش#rust.m3.l2.e2
کوششیں: 0لوڈ ہو رہا ہے…

متغیر کو متغیر بنائیں (مٹ s کو دیں) اور تبدیلی کے فنکشن میں ایک متغیر حوالہ (&mut s) کو منتقل کریں تاکہ اسے سٹرنگ میں ترمیم کرنے کی اجازت دی جاسکے۔

ایڈیٹر لوڈ ہو رہا ہے…
اشارہ دکھائیں۔

`let s` اور call`change(&mut s);`کی بجائے`let mut s` استعمال کریں۔

3 کوششوں کے بعد حل دستیاب ہے۔

ورزش#rust.m3.l2.e3
کوششیں: 0لوڈ ہو رہا ہے…

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 کوششوں کے بعد حل دستیاب ہے۔