Rust Data Types
Every value in Rust has a type — a label that tells the compiler what kind of data it is (a whole number, a decimal, text, true/false, and so on). Knowing the type lets Rust check your code for mistakes before it runs.
As you saw with variables, Rust can usually infer the type for you. But it helps to know the main types by name, because you’ll see them in error messages and function signatures.
Integers (whole numbers)
Section titled “Integers (whole numbers)”Integers are numbers without a decimal point, like 42 or -7. Rust has several integer types that differ by size and whether they allow negative numbers:
| Type | Signed? | Typical use |
|---|---|---|
i32 |
Yes (can be negative) | The default — use this unless you have a reason not to |
u32 |
No (0 and up) | Counts, sizes, things that can’t be negative |
i64 / u64 |
Yes / No | Very large numbers |
usize |
No | Indexing into collections |
fn main() { let temperature = -5; // i32 by default let count: u32 = 100; // explicitly unsigned println!("{temperature} degrees, count is {count}");}Floating-point numbers (decimals)
Section titled “Floating-point numbers (decimals)”For numbers with a decimal point, use floating-point types. There are two: f64 (the default, double precision) and f32.
fn main() { let pi = 3.14159; // f64 by default let price: f32 = 9.99; println!("Pi is {pi}, price is {price}");}Stick with f64 unless you specifically need the smaller f32 — it’s more precise and just as fast on modern hardware.
Booleans
Section titled “Booleans”A boolean (bool) is the simplest type: it’s either true or false. You’ll use these constantly in if statements and conditions.
fn main() { let is_logged_in = true; let has_permission: bool = false; println!("logged in: {is_logged_in}, permission: {has_permission}");}Characters
Section titled “Characters”A char holds a single character, written with single quotes ' '. A Rust char can be any single Unicode scalar value — which covers most emoji, though a few complex ones (like flags or emoji built from multiple joined characters) don’t fit in just one.
fn main() { let letter = 'R'; let symbol = '$'; let crab = '🦀'; println!("{letter} {symbol} {crab}");}Strings (text)
Section titled “Strings (text)”Text in Rust is written with double quotes. There are two string types you’ll meet:
&str— a string slice, usually text you write directly in your code (a “string literal”).String— a growable, owned piece of text you can change and build up.
fn main() { let greeting = "Hello"; // &str let mut name = String::from("Ferris"); // String name.push_str(" the crab"); // Strings can grow println!("{greeting}, {name}!");}Don’t worry about the difference between &str and String yet — it connects to ownership, which you’ll learn soon. For now: use "..." for text and reach for String when you need to build or modify it.
Type annotations
Section titled “Type annotations”Most of the time Rust infers the type. But sometimes it needs a hint — for example, when parsing text into a number. You add a type with a colon:
let x: i32 = 42;let y: f64 = 3.5;let active: bool = true;Quick reference
Section titled “Quick reference”| Type | What it holds | Example |
|---|---|---|
i32 |
Whole number (default) | let n = 42; |
u32 |
Non-negative whole number | let n: u32 = 42; |
f64 |
Decimal number (default) | let pi = 3.14; |
bool |
true or false |
let ok = true; |
char |
One character | let c = 'A'; |
&str |
Text literal | let s = "hi"; |
String |
Growable text | let s = String::from("hi"); |
- Every value has a type; Rust usually infers it.
- Whole numbers →
i32(default). Decimals →f64(default). boolistrue/false;charis a single character in single quotes.- Text is written in double quotes:
&strfor literals,Stringfor growable text.
Quick check
Section titled “Quick check”Quick check
1. What is the default integer type in Rust if you don't specify one?
2. How does Rust distinguish a char literal from a string literal?
3. Which type is a growable, owned piece of text you can modify?
4. What is the default floating-point type in Rust?
5. Which type would `let greeting = "Hello";` infer to?
Score: 0 / 5