کپی کردن تایپ‌ها

در حالی که مفهوم انتقال به صورت پیش‌فرض است، در زبان راست چند نوع خاص به صورت پیش‌فرض کپی می‌شوند:

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 را نقض می‌کند.