Типи які копіюються

Хоча семантика переміщення використовується за замовчуванням, певні типи копіюються за замовчуванням:

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.

Копіювання та клонування – це не одне й те саме:

  • Копіювання стосується побітових копій областей пам’яті та не працює з довільними об’єктами.
  • Копіювання не допускає створювати власну логіку (на відміну від конструкторів копіювання в C++).
  • Клонування — це більш загальна операція, яка також допускає нестандартну поведінку шляхом реалізації трейта Clone.
  • Копіювання не працює з типами, які реалізують трейт Drop.

У наведеному вище прикладі спробуйте наступне:

  • Додайте поле String до struct Point. Це не скомпілюється, оскільки String не є типом Copy.
  • Видаліть Copy з атрибута derive. Помилка компілятора тепер у println! для p1.
  • Покажіть, що це працює, якщо замість цього клонувати p1.

Більше інформації для вивчення

  • Спільні посилання є Copy/Clone, змінні посилання - ні. Це пов'язано з тим, що Rust вимагає, щоб змінювані посилання були ексклюзивними, тому, хоча створення копії спільного посилання є допустимим, створення копії змінюваного посилання порушуватиме правила запозичення Rust.