Working Code
Try running this code in the Rust Playground!
fn main() {
let age: i32 = 20; // Integer
let height: f64 = 175.5; // Float
let is_student: bool = true; // Boolean
let grade: char = 'A'; // Character
println!("Age: {age}");
println!("Height: {height}cm");
println!("Student? {is_student}");
println!("Grade: {grade}");
}
Rust has four basic scalar types.
| Type | Example | Description |
| --------- | ------- | ------------------------------------------- |
| Integer | i32 | Numbers without a decimal point |
| Float | f64 | Numbers with a decimal point |
| Boolean | bool | true or false |
| Character | char | A single character wrapped in single quotes |
You actually don't have to write the types out — Rust can figure them out on its own.
fn main() {
let age = 20; // Inferred as i32
let height = 175.5; // Inferred as f64
let is_happy = true; // Inferred as bool
let emoji = '🦀'; // Inferred as char
println!("{age}, {height}, {is_happy}, {emoji}");
}
Even without explicit type annotations, the Rust compiler looks at the values and determines the types. This is called type inference.
Try It Yourself
Try removing the type annotations (: i32, : f64, etc.) from the code below. Does the output change?
fn main() {
let x: i32 = 42;
let y: f64 = 3.14;
let z: bool = false;
println!("{x}, {y}, {z}");
}
You'll get the same result even without the types. Rust infers them for you. That said, writing out the types can make your code easier for others to read.
"Why?" — Why Do We Need Types?
Computers store the number 42 and the decimal 3.14 in different ways. Integers use one storage format, and floats use another. The compiler needs to know the type to store values correctly in memory and perform accurate operations.
Rust does not allow operations between different types. This helps catch unintended mistakes early.
fn main() {
let a: i32 = 10;
let b: f64 = 3.0;
// This causes an error!
// let result = a + b;
// You need to match the types
let result = a as f64 + b;
println!("Result: {result}");
}
You can convert types using the as keyword. For now, just remember: "if the types differ, you need to align them."
Deep Dive
Varieties of integer types
Rust has a variety of integer types.
| Signed | Unsigned | Size |
| ------ | -------- | ------ |
| i8 | u8 | 8-bit |
| i16 | u16 | 16-bit |
| i32 | u32 | 32-bit |
| i64 | u64 | 64-bit |
i types can hold negative numbers, while u types only hold zero and positive numbers. Larger sizes store a wider range of values.
For now, just remember i32 for integers and f64 for floats. You can learn the rest when you need them!
Adding an integer and a float directly causes an error.
fn main() {
let x = 5;
let y = 2.0;
let sum = x + y;
println!("{sum}");
}
Error message:
error[E0277]: cannot add `{float}` to `{integer}`
--> src/main.rs:4:19
|
4 | let sum = x + y;
| ^ no implementation for `{integer} + {float}`
Translation: "You can't directly add an integer and a float." Fix it with let sum = x as f64 + y; to align the types.
Some languages convert types automatically, but Rust requires you to be explicit — "convert to this type, please." This prevents bugs caused by unexpected conversions.
- Store the first letter of your name in a
charvariable and your age in ani32variable, then print both values on one line. - Create two
i32variables and print the results of addition, subtraction, multiplication, and division. (/is division,%is the remainder operator.)
Q1. What is the default type for a number with a decimal point in Rust?
- A)
float - B)
f32 - C)
f64 - D)
double
Q2. Will the following code run successfully?
fn main() {
let x: i32 = 10;
let y: f64 = 3.0;
let z = x + y;
println!("{z}");
}
- A)
13.0is printed - B)
13is printed - C) A compile error occurs
- D)
10is printed
Q3. What is the type of flag in let flag = true;?
- A)
i32 - B)
string - C)
char - D)
bool