DEV Community

itzlg | cyborg
itzlg | cyborg

Posted on

Rust Ownership Explained: Why Some Values Move and Others Copy

When we assign a value to a new variable in Rust, the value is usually moved. But here’s the catch ,this depends on the type of the value.

Rust plays a little trick when you assign values: some get copied, others get moved, depending on their type.

rust funny image

Primitive Types (Copy)

For primitive types like integers, booleans, and floats, the value is not moved. Instead, it is copied.

Why?

  • They implement the Copy trait.
  • They are stored on the stack.
  • They have a fixed size known at compile time.
  • Copying them is extremely cheap and efficient.

👉 Example:

let x = 5;
let y = x; // y gets a copy, x is still valid
println!("x = {}, y = {}", x, y);

Enter fullscreen mode Exit fullscreen mode

Both x and y remain valid because i32 or u32 implements Copy.

Complex Types (Move)

For types like String, Vec, and most custom structs, Rust does not copy the value by default, it moves it.

Why?

  • They are stored in the heap.
  • Their size is not fixed at compile time.
  • Copying them would require duplicating potentially large amounts of data, which is expensive.

👉 Example:

let s1 = String::from("hello");
let s2 = s1; // ownership moved
// println!("{}", s1); // ❌ Error: s1 is no longer valid

Enter fullscreen mode Exit fullscreen mode

How to Avoid Moving

Sometimes, you don’t want to lose access to the original variable . Rust gives you two options:

Clone it:

let s1 = String::from("hello");
let s2 = s1.clone();
println!("s1 = {}, s2 = {}", s1, s2);

Enter fullscreen mode Exit fullscreen mode

This creates a deep copy of the value (including nested values if present) and allocates new memory in the heap which is safe but potentially expensive
Note: (If it’s not a String, e.g., a struct, you can still call .clone() as long as the type implements the Clone trait.)

Borrow (use references):

let s1 = String::from("hello");
let s2 = &s1; // borrow instead of move
println!("s1 = {}, s2 = {}", s1, s2);

Enter fullscreen mode Exit fullscreen mode

Copy vs Clone

Copy:

  • Shallow copy
  • For small, fixed-size types stored on the stack
  • Very cheap

Clone:

  • Deep copy
  • For complex types stored on the heap
  • Allocates new memory, can be expensive

Rust’s ownership model might feel strict at first, but once you understand the difference between Move, Copy, and Clone, things start to click. The rules are there to help you write safe and efficient code without worrying about memory bugs.

If you found this helpful, please leave a comment or reaction 👏 it really motivates me to share more Rust content.

leave comment

You can also connect with me on X (Twitter): @melovegupta 🚀

Top comments (0)