چک کردن قرض
بررسیکننده ارجاع (borrow checker) در Rust محدودیتهایی بر روی روشهای ارجاع به مقادیر اعمال میکند. برای یک مقدار خاص، در هر زمان:
- شما میتوانید یک یا چند ارجاع اشتراکی به مقدار داشته باشید، یا
- میتوانید دقیقاً یک ارجاع انحصاری به مقدار داشته باشید.
fn main() { let mut a: i32 = 10; let b: &i32 = &a; { let c: &mut i32 = &mut a; *c = 20; } println!("a: {a}"); println!("b: {b}"); }
This slide should take about 10 minutes.
- توجه داشته باشید که نیاز این است که ارجاعات متضاد در همان نقطه وجود نداشته باشند. مهم نیست که ارجاع در کجا dereferenced شود.
- کد بالا کامپایل نمیشود زیرا
a
بهطور همزمان بهصورت قابل تغییر (از طریقc
) و غیرقابل تغییر (از طریقb
) ارجاع داده شده است. - برای اینکه کد کامپایل شود، دستور
!println
مربوط بهb
را قبل از محدودهای کهc
را معرفی میکند، منتقل کنید. - پس از آن تغییر، کامپایلر متوجه میشود که
b
تنها پیش از ارجاع جدید قابل تغییر بهa
از طریقc
استفاده میشود. این ویژگی بررسیکننده ارجاع به نام non-lexical lifetimes است. - محدودیت ارجاع انحصاری بسیار قوی است. Rust از آن برای اطمینان از عدم وقوع دادههای رقابتی (data races) استفاده میکند. Rust همچنین متکی به این محدودیت برای بهینهسازی کد است. به عنوان مثال، مقدار پشت یک ارجاع اشتراکی میتواند بهطور ایمن در یک رجیستر برای طول عمر آن ارجاع کش شود.
- بررسیکننده ارجاع بهگونهای طراحی شده است که بسیاری از الگوهای رایج را پشتیبانی کند، مانند گرفتن ارجاعات انحصاری به فیلدهای مختلف در یک ساختار بهطور همزمان. اما، در برخی موقعیتها، ممکن است که بهطور کامل متوجه وضعیت نشود و این اغلب منجر به "درگیری با borrow checker" میشود.