Primitive Types#

Boolean#

  • bool: represents a boolean value, either true or false.
let is_rust_awesome: bool = true;
let is_python_better = false;

Integer Types#

TypeSizeRange
i88-bit signed-128 to 127
i1616-bit signed-32768 to 32767
i3232-bit signed-2^31 to 2^31-1
i6464-bit signed-2^63 to 2^63-1
i128128-bit signed-2^127 to 2^127-1
isizepointer-sized signedplatform-dependent
u88-bit unsigned0 to 255
u1616-bit unsigned0 to 65535
u3232-bit unsigned0 to 2^32-1
u6464-bit unsigned0 to 2^64-1
u128128-bit unsigned0 to 2^128-1
usizepointer-sized unsignedplatform-dependent

isize and usize are the default types for indexing, collection lengths, and pointer arithmetic.

let age: u8 = 27;
let balance: i32 = -500;
let index: usize = 42;         // used for indexing
let count: isize = -3;         // signed pointer-sized

Floating-Point Types#

  • f32: 32-bit floating-point (single precision)
  • f64: 64-bit floating-point (double precision, default)
let pi: f32 = 3.14159;
let e: f64 = 2.718281828;      // f64 is the default

Character Type#

  • char: represents a single Unicode scalar value (4 bytes).
let letter_a = 'a';
let heart_emoji = '❤';
let pi_char = 'π';

Compound Types#

Tuple#

A fixed-size, ordered collection of values of potentially different types.

let empty_tuple: () = ();
let person: (&str, u8) = ("Alice", 27);

// Destructuring
let (name, age) = person;

// Access by index
let name = person.0;
let age = person.1;

Array#

Fixed-size, homogeneous collection stored on the stack.

let numbers: [i32; 5] = [1, 2, 3, 4, 5];
let zeros = [0u8; 10];         // array of 10 zeros

let first = numbers[0];
let len = numbers.len();       // 5

Slice#

A dynamically-sized view into a contiguous sequence.

let numbers = [1, 2, 3, 4, 5];
let slice: &[i32] = &numbers[1..4];  // [2, 3, 4]

// Slices as function parameters (more flexible than arrays)
fn sum(values: &[i32]) -> i32 {
    values.iter().sum()
}

Collection Types#

String#

  • &str: immutable string slice (usually borrowed, UTF-8)
  • String: owned, heap-allocated, growable UTF-8 string
let literal: &str = "hello";
let owned: String = String::from("hello");
let owned2: String = "hello".to_string();

Vector#

A growable, heap-allocated array.

let mut numbers: Vec<i32> = vec![1, 2, 3, 4, 5];
numbers.push(6);
numbers.pop();          // Some(6)
let len = numbers.len();

HashMap#

A hash map of key-value pairs.

use std::collections::HashMap;

let mut scores: HashMap<&str, i32> = HashMap::new();
scores.insert("Alice", 10);
scores.insert("Bob", 5);

let alice = scores.get("Alice");        // Option<&i32>
scores.entry("Carol").or_insert(0);    // insert if missing

HashSet#

A set of unique values.

use std::collections::HashSet;

let mut set: HashSet<i32> = HashSet::new();
set.insert(1);
set.insert(2);
set.contains(&1);  // true

Custom Types#

Struct#

A custom data structure with named fields.

struct Person {
    name: String,
    age: u8,
}

let alice = Person {
    name: String::from("Alice"),
    age: 27,
};

// Tuple struct
struct Point(f64, f64);
let p = Point(1.0, 2.0);

// Unit struct
struct Marker;

Enumeration#

A type with a fixed set of variants, each potentially holding different data.

enum Direction {
    North,
    South,
    East,
    West,
}

enum Shape {
    Circle(f64),                  // tuple variant
    Rectangle { width: f64, height: f64 },  // struct variant
    Triangle(f64, f64, f64),
}

let d = Direction::North;
let s = Shape::Circle(5.0);

Special Types#

Option#

Represents an optional value that may or may not be present. Replaces null.

let some_number: Option<i32> = Some(42);
let no_number: Option<i32> = None;

// Common methods
some_number.unwrap();             // 42 (panics if None)
some_number.unwrap_or(0);        // 42 (returns default if None)
some_number.is_some();           // true
some_number.is_none();           // false
some_number.map(|n| n * 2);     // Some(84)

Result#

Represents either a success (Ok) or failure (Err).

let ok: Result<i32, &str> = Ok(42);
let err: Result<i32, &str> = Err("Something went wrong");

// Common methods
ok.unwrap();                      // 42 (panics on Err)
ok.unwrap_or(0);                 // 42
ok.is_ok();                      // true
ok.is_err();                     // false
ok.map(|n| n * 2);              // Ok(84)

Smart Pointer Types#

Box#

Allocates a value on the heap. Used for large values, recursive types, and trait objects.

let b: Box<i32> = Box::new(5);
let val = *b;  // dereference

// Recursive type (list)
enum List {
    Cons(i32, Box<List>),
    Nil,
}

Rc#

Reference-counted shared ownership (single-threaded only).

use std::rc::Rc;

let a = Rc::new(5);
let b = Rc::clone(&a);  // increment reference count
println!("{}", Rc::strong_count(&a));  // 2

Arc#

Atomically reference-counted shared ownership (thread-safe).

use std::sync::Arc;
use std::thread;

let value = Arc::new(5);
let value_clone = Arc::clone(&value);

thread::spawn(move || {
    println!("{}", value_clone);
});

Type Aliases#

type UserId = u32;
type Result<T> = std::result::Result<T, String>;

let user_id: UserId = 123;

Function Types#

fn add(a: i32, b: i32) -> i32 {
    a + b
}

let function_pointer: fn(i32, i32) -> i32 = add;
let result = function_pointer(2, 3);  // 5

Reference Types#

let value = 42;
let reference: &i32 = &value;
let mutable_reference: &mut i32 = &mut value.clone();

Raw Pointer Types (unsafe)#

let value = 42;
let raw_pointer: *const i32 = &value;
let mutable_raw_pointer: *mut i32 = &mut value.clone() as *mut i32;

// Dereferencing raw pointers requires unsafe
unsafe {
    println!("{}", *raw_pointer);
}

Troubleshooting#

IssueCauseSolution
mismatched types: expected i32, found i64Rust does not auto-coerce between integer sizesUse as cast or From/Into for safe widening conversions
Integer overflow panic in debug modeDebug builds enable overflow checks by defaultUse wrapping_add, checked_add, or saturating_add for intentional wrapping
cannot index into a value of type Vec<T> with a non-usizeVector indices must be usizeCast the index: v[i as usize] or use .get(i as usize)
type annotations neededCompiler cannot infer a generic typeAdd a turbofish (::<Type>) or annotate the variable: let x: Vec<i32> = ...
Copy cannot be derived for struct containing StringString is heap-allocated and not CopyUse Clone instead, or switch the field to &str with a lifetime
array length must be a constantArray size must be known at compile timeUse Vec<T> for runtime-sized collections, or const for the length

Sources#