Bird
Raised Fist0
Rustprogramming~5 mins

Move semantics in Rust

Choose your learning style10 modes available
Introduction

Move semantics help Rust manage memory safely and efficiently by transferring ownership of data instead of copying it.

When you want to transfer ownership of a value to another variable without copying.
When passing large data to functions to avoid slow copying.
When you want to prevent multiple variables from owning the same data to avoid bugs.
When returning ownership of a value from a function.
When working with types that do not implement the Copy trait.
Syntax
Rust
let x = String::from("hello");
let y = x; // x is moved to y
// x can no longer be used here

After moving, the original variable cannot be used because ownership has transferred.

Move happens automatically for types that do not implement the Copy trait.

Examples
Here, the String value is moved from a to b. Using a after move causes an error.
Rust
let a = String::from("rust");
let b = a; // a is moved to b
// println!("{}", a); // error: a is no longer valid
For simple types like integers, Rust copies the value instead of moving it.
Rust
let x = 5;
let y = x; // x is copied because i32 implements Copy
println!("{}", x); // works fine
Passing s1 to the function moves ownership. After the call, s1 is invalid.
Rust
fn take_ownership(s: String) {
    println!("Got: {}", s);
}

fn main() {
    let s1 = String::from("hello");
    take_ownership(s1);
    // s1 can no longer be used here
}
Sample Program

This program shows how ownership moves from s1 to s2. Trying to use s1 after move causes an error.

Rust
fn main() {
    let s1 = String::from("hello");
    let s2 = s1; // move ownership from s1 to s2
    println!("s2: {}", s2);
    // println!("s1: {}", s1); // this would cause a compile error
}
OutputSuccess
Important Notes

Move semantics prevent double free errors by ensuring only one owner at a time.

Types like String and Vec move by default, while simple types like integers copy.

You can clone data explicitly if you want to keep using the original after copying.

Summary

Move semantics transfer ownership of data instead of copying it.

After a move, the original variable cannot be used.

This helps Rust manage memory safely and efficiently.

Practice

(1/5)
1. What happens to a variable in Rust after its value is moved to another variable?
easy
A. The original variable can no longer be used.
B. The original variable keeps a copy of the value.
C. The original variable is automatically cloned.
D. The original variable becomes a reference to the new variable.

Solution

  1. Step 1: Understand move semantics

    In Rust, moving a value transfers ownership from one variable to another.
  2. Step 2: Effect on original variable

    After the move, the original variable is invalid and cannot be used to prevent double free errors.
  3. Final Answer:

    The original variable can no longer be used. -> Option A
  4. Quick Check:

    Move means original variable unusable [OK]
Hint: Moving means original variable is invalid after transfer [OK]
Common Mistakes:
  • Thinking the original variable still holds a copy
  • Assuming Rust automatically clones on move
  • Confusing move with borrowing
2. Which of the following Rust code snippets correctly moves ownership of a String from a to b?
easy
A. let b = a.clone();
B. let b = &a;
C. let b = a;
D. let b = *a;

Solution

  1. Step 1: Identify move syntax

    Assigning let b = a; moves ownership of a to b.
  2. Step 2: Check other options

    &a borrows, a.clone() copies, *a is invalid for String.
  3. Final Answer:

    let b = a; -> Option C
  4. Quick Check:

    Simple assignment moves ownership [OK]
Hint: Use simple assignment to move ownership, not references or clone [OK]
Common Mistakes:
  • Using references instead of moving
  • Using clone which copies instead of moves
  • Dereferencing a String which is invalid
3. What is the output of this Rust code?
let s1 = String::from("hello");
let s2 = s1;
println!("{}", s1);
medium
A. Compilation error
B. hello
C. Runtime error
D. Empty string

Solution

  1. Step 1: Analyze ownership transfer

    Assigning s2 = s1 moves ownership of the String from s1 to s2.
  2. Step 2: Using moved variable

    Trying to print s1 after move causes a compile-time error because s1 is invalid.
  3. Final Answer:

    Compilation error -> Option A
  4. Quick Check:

    Using moved variable causes compile error [OK]
Hint: Using moved variable causes compile error, not runtime [OK]
Common Mistakes:
  • Expecting output 'hello' despite move
  • Thinking it causes runtime error
  • Assuming Rust clones automatically
4. Identify the error in this Rust code related to move semantics:
fn main() {
    let v = vec![1, 2, 3];
    let v2 = v;
    println!("{}", v.len());
}
medium
A. Vector v cannot be moved to v2.
B. Cannot print vector length with println!.
C. Missing semicolon after let v2 = v.
D. Using v.len() after v was moved to v2.

Solution

  1. Step 1: Understand move of vector

    Assigning v2 = v moves ownership of vector v to v2.
  2. Step 2: Using moved variable causes error

    Calling v.len() after move is invalid and causes compile error.
  3. Final Answer:

    Using v.len() after v was moved to v2. -> Option D
  4. Quick Check:

    Using moved variable causes compile error [OK]
Hint: After move, original variable cannot be used [OK]
Common Mistakes:
  • Thinking vector cannot be moved
  • Ignoring ownership rules after move
  • Confusing move with borrowing
5. Given this Rust function:
fn take_ownership(s: String) {
    println!("{}", s);
}

fn main() {
    let s = String::from("hello");
    take_ownership(s);
    println!("{}", s);
}

What is the best way to fix the code so main can print s after calling take_ownership?
hard
A. Clone s before passing: take_ownership(s.clone()).
B. All of the above.
C. Return s from take_ownership and assign it back.
D. Change take_ownership to take a reference: fn take_ownership(s: &String).

Solution

  1. Step 1: Understand ownership transfer in function

    Passing s to take_ownership moves ownership, invalidating s in main.
  2. Step 2: Ways to keep s usable

    Change take_ownership to take a reference: fn take_ownership(s: &String). borrows s so ownership is not moved.
    Clone s before passing: take_ownership(s.clone()). clones s so original remains.
    Return s from take_ownership and assign it back. returns ownership back to main.
  3. Step 3: Best fix

    All three options correctly fix the problem.
  4. Final Answer:

    All of the above. -> Option B
  5. Quick Check:

    Borrow, clone, or return ownership fixes [OK]
Hint: Borrow, clone, or return ownership to keep variable usable [OK]
Common Mistakes:
  • Ignoring ownership transfer in function calls
  • Not cloning when needed
  • Not returning ownership back
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard