ماڈیول اسباق (1/2)
ملکیت کے قواعد
ملکیت زنگ کی سب سے منفرد خصوصیت ہے۔ یہ زبان کو گاربیج کلیکٹر کی ضرورت کے بغیر یا آپ کو ہیپ میموری کو دستی طور پر ڈیلوکیٹ کرنے پر مجبور کیے بغیر میموری کی حفاظت کی ضمانت دیتا ہے (جیسے C یا C++ میں)۔
ملکیت کے تین اصول
زنگ میں میموری کا انتظام تین آسان اصولوں سے چلتا ہے جو مرتب کرنے والے کے ذریعہ سختی سے چیک کیا جاتا ہے:
- رسٹ میں ہر قدر کا ایک متغیر ہوتا ہے جسے اس کا مالک کہتے ہیں۔
- ایک وقت میں صرف ایک ہی مالک ہو سکتا ہے۔
- جب مالک دائرہ کار سے باہر ہو جاتا ہے تو قیمت خود بخود گر جاتی ہے۔
اسٹیک بمقابلہ ہیپ
ملکیت کو سمجھنے کے لیے، یہ جاننا ضروری ہے کہ ڈیٹا کہاں رہتا ہے:
- اسٹیک: مقررہ سائز کے ڈیٹا کو ذخیرہ کرتا ہے جسے مرتب کرنے کے وقت جانا جاتا ہے (مثال کے طور پر، انٹیجرز، بولین)۔ رسائی انتہائی تیز ہے۔
- ہیپ: ڈائنامک سائز ڈیٹا کو کمپائل کے وقت اسٹور کرتا ہے (جیسے،
String)۔ مختص کرنا سست ہے اور اسٹیک پر ذخیرہ شدہ پوائنٹر کی ضرورت ہے۔
"منتقل" کا تصور
جب ہم ڈھیر سے مختص متغیر کسی دوسرے کو تفویض کرتے ہیں تو، زنگ پہلے متغیر کو باطل کرتے ہوئے قدر کی ملکیت چلتا ہے (یا منتقل) کرتا ہے:
let s1 = String::from("ciao");
let s2 = s1; // Ownership of the text moves to s2. s1 is NO longer usable!
// println!("{}", s1); // COMPILATION ERROR! s1 is "borrow of moved value"
println!("{}", s2); // Valid!یہ رویہ "ڈبل فری ایرر" (دائرہ کار سے باہر جانے پر ایک ہی میموری کو دو بار آزاد کرنے کی کوشش) سے بچتا ہے، کیونکہ صرف s2 میموری کو آزاد کرے گا۔
"کلون" کا تصور (ڈیپ کاپی)
اگر ہمیں واضح طور پر String کے پورے مواد کو کاپی کرنے کی ضرورت ہے (اسٹیک پوائنٹرز اور ہیپ میں اصل ٹیکسٹ ڈیٹا دونوں)، تو ہم .clone() طریقہ استعمال کر سکتے ہیں۔ یہ ڈھیر پر موجود ڈیٹا کو مکمل طور پر ڈپلیکیٹ کرتا ہے، اصل اور نئے متغیر دونوں کو درست رکھتے ہوئے، نئی میموری مختص کرنے کے لیے پرفارمنس اوور ہیڈ کی قیمت پر:
let s1 = String::from("ciao");
let s2 = s1.clone(); // Deep copy. Both variables remain valid!
println!("s1: {}, s2: {}", s1, s2);"کاپی" کا تصور
اسٹیک پر مکمل طور پر ذخیرہ شدہ سادہ قسموں کے لیے (جیسے انٹیجرز i32، booleans bool، حروف char)، اسائنمنٹ ایک حقیقی خودکار اتلی کاپی انجام دیتی ہے، یعنی دونوں متغیرات درست رہتے ہیں:
let x = 5;
let y = x; // Copies the value 5 onto the stack. Both variables are usable!
println!("x: {}, y: {}", x, y); // Valid!خود ہی آزمائیں۔
ایک String s1 کا اعلان کریں جس میں متن 'ہیلو' ہو۔ s1 کو s2 کو تفویض کریں (تاکہ ملکیت منتقل ہو سکے)۔ آخر میں، پرنٹ ایل این کا استعمال کرتے ہوئے s2 پرنٹ کریں!
اشارہ دکھائیں۔
ملکیت کو `s2` کو منتقل کرنے کے لیے `let s2 = s1;` کا استعمال کریں اور اسے `println!('{}', s2);` کے ساتھ پرنٹ کریں۔
3 کوششوں کے بعد حل دستیاب ہے۔
5 کی قدر کے ساتھ ایک عدد متغیر x کا اعلان کریں۔ x کو y کو تفویض کریں (ایک کاپی انجام دیتے ہوئے)۔ آخر میں، ایک ہی println میں x اور y دونوں کو پرنٹ کریں! بیان
اشارہ دکھائیں۔
`let y = x;` کریں اور پھر دونوں قدروں کو پرنٹ کریں، جیسے، `println!('{} {}', x, y);`۔
3 کوششوں کے بعد حل دستیاب ہے۔
Declare a String s1 with the value "Rust". Create a deep copy of s1 in a new variable s2 using the clone method. Finally, print both s1 and s2 separated by a space using the println! macro.
اشارہ دکھائیں۔
Use `let s2 = s1.clone();` to deep copy the value of `s1` into `s2`, then print them with `println!("{} {}", s1, s2);`.
3 کوششوں کے بعد حل دستیاب ہے۔