Rust Data Types
Every value in Rust has a type. The type tells Rust how much memory to use and what operations are allowed on that value. Rust is a statically typed language — the type of every variable must be known at compile time.
Two Categories of Types
Data Types in Rust
│
├── Scalar Types ← Hold a single value
│ ├── Integer
│ ├── Float
│ ├── Boolean
│ └── Character
│
└── Compound Types ← Hold multiple values
├── Tuple
└── Array
Scalar Types
1. Integers
An integer is a whole number with no decimal point. Rust gives you several integer types based on two factors: how many bits of memory the number uses, and whether it can hold negative numbers.
Type Bits Range ------ ---- ----- i8 8 -128 to 127 i16 16 -32,768 to 32,767 i32 32 -2 billion to 2 billion (default) i64 64 very large range u8 8 0 to 255 u16 16 0 to 65,535 u32 32 0 to 4 billion u64 64 very large positive range
The letter i means signed (can be negative). The letter u means unsigned (positive only). The number shows how many bits the type uses. If you do not specify a type, Rust uses i32 as the default for integers.
The Parking Lot Diagram
u8 parking lot: [ 0 ][ 1 ][ 2 ] ... [ 255 ] ← 256 spaces, no negatives i8 parking lot: [-128]...[ 0 ]...[ 127 ] ← 256 spaces, half negative
let small: u8 = 200; let big: i64 = -9_000_000_000; let default_int = 42; ← Rust infers i32
You can use underscores in number literals to make large numbers easier to read: 1_000_000 is the same as 1000000.
2. Floating-Point Numbers
A float is a number with a decimal point. Rust provides two float types: f32 (32 bits) and f64 (64 bits). The default is f64 because modern computers handle it at the same speed as f32 but with more precision.
let height: f32 = 5.9; let price: f64 = 99.99; let default_float = 3.14; ← Rust infers f64
3. Booleans
A boolean holds one of two values: true or false. It uses 1 byte of memory. Booleans appear most often in conditions and control flow.
let is_logged_in: bool = true; let has_error: bool = false;
4. Characters
A character holds a single letter, digit, or symbol. In Rust, characters use single quotes and take 4 bytes of memory. They can hold any Unicode character — including emoji and letters from any language.
let letter: char = 'A'; let digit: char = '7'; let emoji: char = '😀';
The Character vs String Diagram
char = one single character → 'A' (single quotes) &str = a sequence of chars → "Hello" (double quotes)
Compound Types
1. Tuples
A tuple groups multiple values of different types into one unit. Once you create a tuple, its size is fixed — you cannot add or remove elements.
let person: (i32, f64, char) = (30, 5.9, 'M');
Access individual values using a dot followed by the position number, starting from 0:
let age = person.0; ← 30 let height = person.1; ← 5.9 let gender = person.2; ← 'M'
You can also destructure a tuple into separate variables:
let (age, height, gender) = person;
println!("Age: {}, Height: {}, Gender: {}", age, height, gender);
The Gift Box Diagram
(30, 5.9, 'M') ↑ ↑ ↑ .0 .1 .2 Three items packed together, each with its own type.
2. Arrays
An array holds multiple values of the same type. Arrays have a fixed length — you cannot grow or shrink them. Every element sits next to the others in memory, making arrays very fast to access.
let scores: [i32; 5] = [10, 20, 30, 40, 50];
The type annotation [i32; 5] means: an array of 5 integers. Access elements using square brackets with the index (starting at 0):
let first = scores[0]; ← 10 let last = scores[4]; ← 50
Create an array where all elements have the same value:
let zeros = [0; 8]; ← [0, 0, 0, 0, 0, 0, 0, 0]
The Egg Carton Diagram
scores: [ 10 | 20 | 30 | 40 | 50 ] index: 0 1 2 3 4 scores[0] = 10 scores[2] = 30
Tuple vs Array
Feature Tuple Array -------- ------ ------ Types Can mix different types Same type only Size Fixed Fixed Access .0 .1 .2 [0] [1] [2] Use case Group related data List of same-type items
Type Inference and Annotation
Rust can figure out the type from context in most cases. You only need to write the type when Rust cannot figure it out, or when you want to use a specific type instead of the default.
let x = 5; ← Rust infers i32 let y: u8 = 5; ← You specify u8 let z = 5_u8; ← Inline type suffix, also u8
Integer Overflow
If you store a value larger than a type can hold, that is called an overflow. In debug mode, Rust panics (crashes) when this happens. In release mode, the value wraps around. Use types large enough for your data to avoid this.
let x: u8 = 255; let y: u8 = x + 1; ← Overflow! u8 cannot hold 256.
Quick Reference
i32 ← Default integer type f64 ← Default float type bool ← true or false char ← Single character, 4 bytes, single quotes (T1, T2) ← Tuple: mixed types, fixed size [T; N] ← Array: same type, fixed size N
