کپی کردن تایپها
در حالی که مفهوم انتقال به صورت پیشفرض است، در زبان راست چند نوع خاص به صورت پیشفرض کپی میشوند:
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 را نقض میکند.