کپی کردن تایپها
در حالی که مفهوم انتقال به صورت پیشفرض است، در زبان راست چند نوع خاص به صورت پیشفرض کپی میشوند:
fn main() { let x = 42; let y = x; println!("x: {x}"); // would not be accessible if not Copy println!("y: {y}"); }
این انواعداده ویژگی Copy را پیادهسازی کردهاند.
البته که میتوان برای نوعهایی که میسازید هم مفهوم کپی را داشته باشید:
#[derive(Copy, Clone, Debug)] struct Point(i32, i32); fn main() { let p1 = Point(3, 4); let p2 = p1; println!("p1: {p1:?}"); println!("p2: {p2:?}"); }
- پس از انتساب، هر دو
p1وp2دادههای خود مستقل خود را دارند. - همچنین میتوانیم از
p1.clone()برای کپی صریح دادهها استفاده کنیم.
This slide should take about 5 minutes.
کپیبرداری و کلونسازی یکسان نیستند:
- کپیبرداری به کپیهای بیت به بیت از مناطق حافظه اشاره دارد و روی همه انواع تعریف شده توسط شما کار نمیکند.
- کپیبرداری اجازه منطق سفارشی را نمیدهد (بر خلاف کپی constructors در C++).
- کلونسازی یک عملیات عمومیتر است و همچنین با پیادهسازی ویژگی
Cloneامکان رفتار سفارشی را فراهم میکند. - کپیبرداری روی انواع دادهای که ویژگی Drop را پیاده سازی کرده اند کار نمیکند.
در مثال بالا، موارد زیر را امتحان کنید:
- یک فیلد
Stringبهstruct Pointاضافه کنید. کامپایل نمیشود زیراStringیک نوعCopyنیست. - ویژگی
Copyرا از صفتderiveحذف کنید. اکنون خطای کامپایلر در!printlnبرایp1قرار دارد. - نشان دهید که اگر
p1را به جای کپی آن کلون کنید، کار میکند.
برای کاوش بیشتر
- ارجاعات مشترک (
shared references) دارای ویژگیCopy/Cloneهستند، اما ارجاعات قابل تغییر (mutable references) اینطور نیستند. این به این دلیل است که Rust نیاز دارد که ارجاعات قابل تغییر منحصر به فرد باشند، بنابراین در حالی که کپی کردن یک ارجاع مشترک معتبر است، ایجاد یک کپی از یک ارجاع قابل تغییر قوانین قرضگیری Rust را نقض میکند.