CodeBlanks Logo Icon CodeBlanks

Move semantics

See how ownership transfers through moves.

Move semantics

When a value holding heap data, such as a String, is assigned to another variable, the data isn't copied; ownership moves. The old variable becomes invalid:

let a = String::from("kitap");
let b = a;               // ownership moved to b
// println!("{a}");      // error E0382: use of a moved value
println!("{b}");

This way two variables never try to free the same memory twice (a double-free bug becomes impossible).

clone is explicit

Rust doesn't hide copies: an expensive deep copy always appears in the code as .clone().

let a = String::from("kitap");
let b = a.clone();      // new memory is allocated
println!("{a} {b}");    // both are valid

A move is cheap (only the pointer, length and capacity are copied); that's why Rust chooses moving by default. In most cases using a reference (&a) is better than clone.

Practice Move and copy

Declare let a = String::from("kitap");. Copy it with let b = a.clone(); and move it with let c = a;. Print b and c on one line (a must no longer be used).

Starter code

main.rs
fn main() {
    // buraya yaz
}

Sample solution

main.rs
fn main() {
    let a = String::from("kitap");
    let b = a.clone();
    let c = a;
    println!("{} {}", b, c);
}

Expected output

kitap kitap

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What is used to get a real copy of a <code>String</code>?

  • &a
  • copy(a)
  • .clone() Correct answer
  • let b = a;

Explanation: clone makes a deep copy of the heap data, giving two independent Strings. Because it can be expensive, it is written explicitly.

2 Deep copy

Question
let a = vec![1, 2, 3];
let b = a.____();
println!("{:?} {:?}", a, b);
Answer
let a = vec![1, 2, 3];
let b = a.clone();
println!("{:?} {:?}", a, b);

Explanation: clone copies the heap data and creates an independent new value.

3 Operation and result

Term Meaning
let b = a; (String) Move, a invalid
let b = a.clone(); Deep copy, both valid
E0382 Use of a moved value
Cost of a move Only 3 words

All lessons in Beginner