مالکیت (Ownership)، وام‌گیری (Borrowing)، طول عمرها (Lifetimes) در Rust

ایجاد شده توسط دکتر مصطفی جلیلی در آموزش برنامه نویسی Rust 7 ژوئن 2025
اشتراک گذاری


مالکیت، وام‌گیری و طول‌عمر در Rust


یکی از مهم‌ترین دلایلی که Rust را به زبانی ایمن، بدون نیاز به Garbage Collector و در عین حال قدرتمند و سریع تبدیل کرده، سیستم مالکیت حافظه آن است. در این بخش با مفاهیمی آشنا می‌شویم که اساس ایمنی حافظه در Rust را تشکیل می‌دهند: مالکیت (Ownership)، وام‌گیری (Borrowing)، طول‌عمر (Lifetimes) و مفاهیم مرتبط

مالکیت (Ownership) و قوانین آن


در Rust، هر مقدار (value) یک مالک (owner) دارد. وقتی متغیری مقداری را در اختیار می‌گیرد، مالک آن مقدار می‌شود.


قوانین اصلی مالکیت:

1- هر مقدار دقیقاً یک مالک دارد.

2 - وقتی مالک از بین برود (از اسکوپ خارج شود)، مقدار نیز آزاد می‌شود.

3 - اگر مالکیت را منتقل کنید، دیگر نمی‌توانید از متغیر قبلی استفاده کنید.


مثال ساده:


fn main() {
let name = String::from("Ali");
let new_name = name; // مالکیت به new_name منتقل شد
// println!("{}", name); // خطا! چون name دیگر مالک نیست
}

در این مثال، با انتساب name به new_name، مالکیت رشته منتقل می‌شود و استفاده از name پس از آن مجاز نیست.




وام‌گیری (Borrowing) و ارجاع‌ها


گاهی اوقات می‌خواهیم به یک مقدار دسترسی داشته باشیم بدون این‌که مالک آن شویم. در این حالت، از مفهوم وام‌گیری استفاده می‌کنیم؛ یعنی ارسال یک ارجاع (reference).


ارجاع خواندنی (Immutable Borrow):


fn print_name(name: &String) {
println!("Name: {}", name);
}
fn main() {
let my_name = String::from("Sara");
print_name(&my_name); // ارجاع داده‌ایم، نه مالکیت
println!("{}", my_name); // مشکلی نیست، چون مالکیت همچنان با ماست
}

ارجاع قابل تغییر (Mutable Borrow):


برای تغییر یک مقدار، باید وام‌گیری را به صورت قابل تغییر انجام دهید:


fn append_hello(text: &mut String) {
text.push_str(" سلام");
}
fn main() {
let mut msg = String::from("سلام");
append_hello(&mut msg);
println!("{}", msg); // خروجی: سلام سلام
}

محدودیت‌های مهم وام‌گیری:

- در یک زمان فقط یک ارجاع قابل تغییر مجاز است.

- یا چند ارجاع خواندنی، ولی نه هر دو هم‌زمان.


این قوانین باعث می‌شوند که شرایط خطرناکی مثل race condition به‌صورت compile-time شناسایی شوند.




طول‌عمرها (Lifetimes)


ارجاع‌ها در Rust ممکن است به داده‌هایی اشاره کنند که دیگر وجود ندارند. برای جلوگیری از این خطاها، Rust از مفهومی به نام طول‌عمر (lifetime) استفاده می‌کند.


چرا Lifetimes نیاز داریم؟


fn get_ref() -> &String {
let s = String::from("سلام");
&s // خطا: s از بین می‌رود و ارجاع بی‌اعتبار می‌شود
}

در اینجا ارجاعی برمی‌گردد به مقداری که در داخل تابع تعریف شده و با پایان تابع پاک می‌شود.


تعریف طول‌عمر:


با استفاده از 'a و مشابه آن، می‌توان مشخص کرد که طول‌عمر یک ارجاع چقدر است:


fn longer<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}

در این مثال تابع longer مشخص می‌کند که مقدار برگشتی حداقل تا زمانی زنده است که x و y زنده هستند.


Rust در بسیاری از موارد lifetimes را به‌صورت خودکار (lifetime elision) تشخیص می‌دهد، ولی در توابع پیچیده یا بازگشتی باید به‌صراحت مشخص شوند.




Copy، Clone و Drop


Copy Trait:


برخی نوع‌ها مانند i32, bool, char به‌صورت پیش‌فرض قابلیت کپی (Copy) دارند. وقتی این نوع‌ها را منتقل می‌کنید، نسخه‌ای جدید ساخته می‌شود، نه این‌که مالکیت منتقل شود.


let a = 10;
let b = a; // کپی شده، a همچنان قابل استفاده است

Clone Trait:


برای ساخت کپی از نوع‌هایی مثل String که به‌صورت پیش‌فرض Move می‌شوند، باید از متد clone() استفاده کرد:


let s1 = String::from("Hello");
let s2 = s1.clone(); // کپی عمیق

Drop Trait:


وقتی یک مقدار از اسکوپ خارج می‌شود، متد drop برای آزادسازی منابع اجرا می‌شود. معمولاً خودتان آن را نمی‌نویسید، اما می‌توانید آن را override کنید.


struct Log;
impl Drop for Log {
fn drop(&mut self) {
println!("Log حذف شد");
}
}
fn main() {
let _l = Log {};
} // در اینجا drop اجرا می‌شود



جمع‌بندی


در این بخش یاد گرفتیم:

- مالکیت (Ownership) مفهوم پایه‌ای مدیریت حافظه در Rust است.

- با وام‌گیری (Borrowing) می‌توان از مقادیر استفاده کرد بدون گرفتن مالکیت آن‌ها.

- طول‌عمرها (Lifetimes) به Rust کمک می‌کنند که ارجاع‌هایی معتبر و ایمن داشته باشیم.

- ویژگی‌هایی مانند Copy, Clone و Drop رفتار نوع‌ها را هنگام کپی و آزادسازی مشخص می‌کنند.


این مفاهیم، پایه‌ی ایمنی حافظه در Rust هستند و درک آن‌ها برای ورود به برنامه‌نویسی حرفه‌ای با این زبان، ضروری است.

نظرات (0)

اشتراک گذاری

این پست را با دیگران به اشتراک بگذارید

تنظیمات GDPR

When you visit any of our websites, it may store or retrieve information on your browser, mostly in the form of cookies. This information might be about you, your preferences or your device and is mostly used to make the site work as you expect it to. The information does not usually directly identify you, but it can give you a more personalized web experience. Because we respect your right to privacy, you can choose not to allow some types of cookies. Click on the different category headings to find out more and manage your preferences. Please note, that blocking some types of cookies may impact your experience of the site and the services we are able to offer.