Типи які копіюються
Хоча семантика переміщення використовується за замовчуванням, певні типи копіюються за замовчуванням:
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.