← thecodex.expert · The Codex Family of Knowledge
Rust

Data Types

Rust spells out exactly how many bits an integer uses in its own name — i32, u64, i8 — rather than leaving it to the platform.

Rust 1.95+ i32 default Last verified:
Where this bites you

Rust arrays are bounds-checked — but only at runtime, when the index isn't a literal the compiler can check in advance. An off-by-one like asking for index len() instead of len() - 1 compiles cleanly: there's nothing wrong with the type, only the value. The program builds, runs, and panics the moment it actually reaches that line, with no warning beforehand.

Rustoob_bug.rs
fn main() {
    let scores: [i32; 3] = [90, 85, 78];
    let last_index = scores.len();
    println!("{}", scores[last_index]);
}
// index out of bounds: the len is 3 but the index is 3
Canonical Definition

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.

Rustintegers.rs
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.

Rusttuples.rs
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.

Rustarrays.rs
let scores: [i32; 3] = [90, 85, 78];
println!("{}", scores[0]);   // 90

let zeros = [0; 5];   // shorthand: [0, 0, 0, 0, 0]

That's the trap in the bug above: scores.len() is 3 for a 3-element array, but valid indices only run 0 to 2 — asking for index 3 panics with "index out of bounds." Rather than doing the off-by-one arithmetic by hand, methods like .last() sidestep indexing entirely and return an Option instead of panicking:

Rustoob_fix.rs
fn main() {
    let scores: [i32; 3] = [90, 85, 78];
    let last = scores.last().expect("scores is never empty");
    println!("{}", last);
}
// 78

Sources

1
The Rust Project. The Rust Programming Language, "Data Types", doc.rust-lang.org/book/ch03-02.