Rust’s scalar types are integers (signed i8–i128, unsigned u8–u128, plus pointer-sized isize/usize), floating-point (f32, f64), bool, and char (a 4-byte Unicode scalar value, unlike a single byte in C). Compound types group multiple values into one: a tuple bundles a fixed number of values of possibly different types, and an array holds a fixed number of values of the SAME type, with its length baked into the type itself.
Integers: the width is in the name
Unlike C's platform-dependent int, a Rust integer type states its exact bit width and signedness directly: i32 is a signed 32-bit integer, u8 an unsigned 8-bit integer (a "byte"). i32 is the default when a type isn't specified and can't be inferred otherwise.
let a: i32 = -42;
let b: u8 = 255; // max value for an 8-bit unsigned int
let c = 100; // inferred as i32, the default
// let bad: u8 = 256; // COMPILE ERROR: 256 doesn't fit in a u8 (0-255)Tuples: fixed-size, mixed types
A tuple groups a fixed number of values, each of any type, accessed by position with dot notation or unpacked via destructuring.
let person: (&str, i32, bool) = ("Alice", 30, true);
println!("{}", person.0); // "Alice" — access by position
let (name, age, _active) = person; // destructuring
println!("{} is {}", name, age);Arrays: fixed-size, same type
Unlike a tuple, every element of an array is the same type, and the length is part of the type ([i32; 5] and [i32; 10] are different types) — for a growable list of the same type, Rust code reaches for Vec<T> instead, covered in the next chapter.
let scores: [i32; 3] = [90, 85, 78];
println!("{}", scores[0]); // 90
let zeros = [0; 5]; // shorthand: [0, 0, 0, 0, 0]