Семантика переміщення
Присвоєння переміщує володіння між змінними:
fn main() { let s1: String = String::from("Привіт!"); let s2: String = s1; println!("s2: {s2}"); // println!("s1: {s1}"); }
- Присвоєння 
s1доs2переміщує володіння. - Коли 
s1виходить за межі області видимості, нічого не відбувається: вона нічим не володіє. - Коли 
s2виходить за межі, дані рядка звільняються. 
Перед переміщенням до s2:
Після переміщення до s2:
Коли ви передаєте значення функції, це значення присвоюється параметру функції. Це переміщує володіння:
fn say_hello(name: String) { println!("Привіт {name}") } fn main() { let name = String::from("Alice"); say_hello(name); // say_hello(name); }
- 
Зауважте, що це протилежність поведінки за замовчуванням у C++, яка копіює за значенням, якщо ви не використовуєте
std::move(і конструктор переміщення визначено!). - 
Переміщується лише володіння. Чи генерується машинний код для маніпулювання самими даними - це питання оптимізації, і такі копії агресивно оптимізуються.
 - 
Прості значення (наприклад, цілі числа) можна позначити
Copy(див. наступні слайди). - 
У Rust клони є явними (за допомогою
clone). 
У прикладі say_hello:
- З першим викликом 
say_hellomainвтрачає володінняname. Після цьогоnameбільше не можна використовувати вmain. - Пам’ять купи, виділена для 
name, буде звільнено в кінці функціїsay_hello. mainможе зберігти володіння, якщо передастьnameяк посилання (&name) і якщоsay_helloприймає посилання як параметр.- Крім того, 
mainможе передати клонnameпід час першого виклику (name.clone()). - Rust ускладнює ненавмисне створення копій, на відмінну від C++, роблячи семантику переміщення за замовчуванням і змушуючи програмістів робити клони явними.
 
Більше інформації для вивчення
Захисні копії в сучасному C++
Сучасний C++ вирішує це інакше:
std::string s1 = "Cpp";
std::string s2 = s1;  // Дублювання даних в s1.
- Дані купи з 
s1дублюються, аs2отримує власну незалежну копію. - Коли 
s1іs2виходять за межі видимості, кожен з них звільняє власну пам’ять. 
Перед копіюванням:
Після копіювання:
Ключові моменти:
- 
C++ зробив дещо інший вибір, ніж Rust. Оскільки
=копіює дані, дані рядка потрібно клонувати. Інакше ми отримаємо подвійне звільнення, коли будь-який рядок виходить за межі видимості. - 
C++ також має
std::move, який використовується щоб вказати коли значення можна перемістити. Якби приклад бувs2 = std::move(s1), розподілу купи не відбулося б. Після переміщенняs1буде в діючому, але не визначеному стані. На відміну від Rust, програмісту дозволено використовуватиs1. - 
На відміну від Rust,
=у C++ може виконувати довільний код, який визначається типом, який копіюється або переміщується.