মূল কন্টেন্টে যান
মডিউল 3 · 1-এর পাঠ 2কোর্সে 5/14~15 min
মডিউল পাঠ (1/2)

মালিকানার নিয়ম

মালিকানা মরিচা সবচেয়ে অনন্য বৈশিষ্ট্য. এটি ভাষাকে আবর্জনা সংগ্রাহকের প্রয়োজন ছাড়াই বা আপনাকে ম্যানুয়ালি হিপ মেমরি (যেমন C বা C++ তে) ডিলোকেট করতে বাধ্য না করে মেমরির নিরাপত্তার গ্যারান্টি দেয়।

মালিকানার তিনটি নিয়ম

মরিচা-এ মেমরি ম্যানেজমেন্ট কম্পাইলার দ্বারা কঠোরভাবে চেক করা তিনটি সহজ নিয়ম দ্বারা পরিচালিত হয়:

  1. মরিচা-এর প্রতিটি মানের একটি ভেরিয়েবল থাকে যার মালিক বলা হয়।
  2. এক সময়ে শুধুমাত্র একজন মালিক থাকতে পারে।
  3. মালিক সুযোগের বাইরে চলে গেলে, মান স্বয়ংক্রিয়ভাবে বাদ দেওয়া হয়।

স্ট্যাক বনাম স্তূপ

মালিকানা বোঝার জন্য, ডেটা কোথায় থাকে তা জানা গুরুত্বপূর্ণ:

  • স্ট্যাক: কম্পাইলের সময় পরিচিত নির্দিষ্ট-আকারের ডেটা সঞ্চয় করে (যেমন, পূর্ণসংখ্যা, বুলিয়ান)। অ্যাক্সেস অত্যন্ত দ্রুত।
  • হিপ: কম্পাইলের সময় অজানা গতিশীল-আকারের ডেটা সঞ্চয় করে (যেমন, String)। বরাদ্দ ধীর এবং স্ট্যাকে সংরক্ষিত একটি পয়েন্টার প্রয়োজন।

"সরানো" ধারণা

যখন আমরা একটি হিপ-অ্যালোকেটেড ভেরিয়েবল অন্যকে বরাদ্দ করি, তখন প্রথম ভেরিয়েবলটিকে বাতিল করে, রাস্ট মুভ (বা হস্তান্তর) করে মানের মালিকানা:

Rust
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() পদ্ধতি ব্যবহার করতে পারি। নতুন মেমরি বরাদ্দের জন্য পারফরম্যান্স ওভারহেডের খরচে এটি মূল এবং নতুন ভেরিয়েবল উভয়কেই বৈধ রেখে, হিপের ডেটা সম্পূর্ণরূপে নকল করে:

Rust
let s1 = String::from("ciao");
let s2 = s1.clone(); // Deep copy. Both variables remain valid!
println!("s1: {}, s2: {}", s1, s2);

"কপি" এর ধারণা

স্ট্যাক-এ সম্পূর্ণরূপে সংরক্ষিত সাধারণ প্রকারের জন্য (যেমন পূর্ণসংখ্যা i32, বুলিয়ান bool, অক্ষর char), অ্যাসাইনমেন্টটি একটি প্রকৃত স্বয়ংক্রিয় অগভীর অনুলিপি সম্পাদন করে, যার অর্থ উভয় ভেরিয়েবল বৈধ থাকে:

Rust
let x = 5;
let y = x; // Copies the value 5 onto the stack. Both variables are usable!
println!("x: {}, y: {}", x, y); // Valid!

নিজে চেষ্টা করে দেখুন

ব্যায়াম#rust.m3.l1.e1
প্রচেষ্টা: 0লোড হচ্ছে...

'হ্যালো' টেক্সট ধারণকারী একটি স্ট্রিং s1 ঘোষণা করুন। s1 কে s2 বরাদ্দ করুন (যাতে মালিকানা সরানো যায়)। অবশেষে, println ব্যবহার করে s2 প্রিন্ট করুন!

সম্পাদক লোড হচ্ছে...
ইঙ্গিত দেখান

`s2`-এ মালিকানা হস্তান্তর করতে `let s2 = s1;` ব্যবহার করুন এবং `println!('{}', s2);` দিয়ে মুদ্রণ করুন।

সমাধান 3 প্রচেষ্টার পরে উপলব্ধ

ব্যায়াম#rust.m3.l1.e2
প্রচেষ্টা: 0লোড হচ্ছে...

5 এর মান সহ একটি পূর্ণসংখ্যা ভেরিয়েবল x ঘোষণা করুন। x কে y বরাদ্দ করুন (একটি অনুলিপি সম্পাদন করা)। অবশেষে, একই println এ x এবং y উভয়ই প্রিন্ট করুন! বিবৃতি

সম্পাদক লোড হচ্ছে...
ইঙ্গিত দেখান

`লেট y = x;` করুন এবং তারপর উভয় মান প্রিন্ট করুন, যেমন, `println!('{} {}', x, y);`।

সমাধান 3 প্রচেষ্টার পরে উপলব্ধ

ব্যায়াম#rust.m3.l1.e3
প্রচেষ্টা: 0লোড হচ্ছে...

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 প্রচেষ্টার পরে উপলব্ধ