LibraryVariables and Data Moves

Variables and Data Moves

Learn about Variables and Data Moves as part of Rust Systems Programming

Rust Fundamentals: Variables and Data Moves

Welcome to the core concepts of Rust's memory management: variables and data moves. Understanding how Rust handles data is crucial for writing safe, efficient, and concurrent code. This module will explore how variables are declared, how data is assigned, and the fundamental concept of 'moving' ownership.

Declaring Variables in Rust

In Rust, variables are declared using the

code
let
keyword. By default, variables are immutable, meaning their values cannot be changed after they are initialized. To create a mutable variable, you use
code
let mut
.

What keyword is used to declare a variable in Rust?

The let keyword.

How do you declare a mutable variable in Rust?

You use let mut.

Data Types and Initialization

Rust is statically typed, meaning the compiler knows the type of every variable at compile time. You can often let the compiler infer the type, or you can explicitly annotate it. For example,

code
let x: i32 = 5;
declares an integer variable
code
x
of type
code
i32
.

Rust also supports various data types, including integers (

code
i32
,
code
u64
), floating-point numbers (
code
f32
,
code
f64
), booleans (
code
bool
), characters (
code
char
), and compound types like tuples and arrays.

The Concept of Ownership

Rust's unique ownership system is key to its memory safety guarantees without a garbage collector. Every value in Rust has a variable that's called its owner. There can only be one owner at a time. When the owner goes out of scope, the value will be dropped.

Ownership: One owner, dropped when owner goes out of scope.

When a variable that owns data goes out of scope, Rust automatically cleans up the data. This prevents memory leaks.

Consider a String type. When you create a String, the variable holding it is its owner. If you assign this String to another variable, ownership is moved. The original variable is no longer valid. This prevents double-free errors because only one variable is responsible for deallocating the memory.

Data Moves vs. Copies

Rust distinguishes between types that are 'copied' and types that are 'moved'. Types that implement the

code
Copy
trait (like integers, booleans, and characters) are copied by default. When you assign them to another variable, both variables hold independent copies of the data.

However, types that manage resources on the heap (like

code
String
,
code
Vec
, and
code
Box
) do not implement the
code
Copy
trait. When you assign a value of such a type to another variable, ownership is moved. The original variable becomes invalid to prevent issues like double-freeing memory.

Type BehaviorAssignment ActionOriginal Variable StatusMemory Management
Types implementing Copy (e.g., i32, bool)Copies the valueRemains valid and holds its own copyEach variable manages its own independent data
Types not implementing Copy (e.g., String, Vec<T>)Moves ownership of the valueBecomes invalid (dangling pointer if used)The new owner is responsible for deallocating the data

Think of Copy types like making a photocopy of a document. You have two identical, independent documents. Think of Move types like transferring ownership of a car. Only one person owns it at a time, and the previous owner can no longer drive it.

Illustrating Data Moves

Let's see this in action. When you assign a

code
String
from one variable to another, the ownership is transferred. Attempting to use the original variable after the move will result in a compile-time error, enforcing Rust's safety guarantees.

Consider a String named s1 holding the value "hello". When we write let s2 = s1;, ownership of the string data (which is on the heap) is moved from s1 to s2. s1 is no longer valid. If we then try to print s1, the Rust compiler will catch this as an error.

📚

Text-based content

Library pages focus on text content

What happens to the original variable when ownership of a non-Copy type (like String) is moved to another variable?

The original variable becomes invalid.

Functions and Ownership

Functions also interact with ownership. When you pass a value to a function, ownership is moved. If the function needs to return the value, it can return ownership back to the caller.

This understanding of variables, data types, and ownership is fundamental to writing idiomatic and safe Rust code. It's a powerful system that prevents common programming errors related to memory management.

Learning Resources

The Rust Programming Language - Variables and Mutability(documentation)

The official Rust book provides a comprehensive explanation of variables, mutability, and shadowing.

The Rust Programming Language - Ownership(documentation)

This chapter delves deep into Rust's ownership system, explaining its rules and implications.

The Rust Programming Language - Understanding Move Semantics(documentation)

Explains the distinction between moving and copying data in Rust, focusing on heap-allocated data.

Rust by Example - Variables(tutorial)

A practical, code-focused introduction to variable bindings and mutability in Rust.

Rust by Example - Ownership(tutorial)

Illustrates the concept of moving ownership with clear code examples.

Rust Ownership: The Core Concept Explained(video)

A video tutorial explaining the fundamental principles of Rust's ownership system.

Rust Data Types and Ownership(video)

A visual explanation of Rust's data types and how ownership affects them.

Rust Ownership and Borrowing - A Deep Dive(blog)

A blog post offering a detailed exploration of Rust's ownership and borrowing rules.

Rust's Ownership Model: A Paradigm Shift(blog)

An article discussing the unique aspects and benefits of Rust's ownership model.

Rust (programming language) - Wikipedia(wikipedia)

Provides a general overview of Rust, including its memory safety features and ownership system.