Values and Types in Rust
Rust is statically typed with powerful type inference. Types are explicit in function signatures; local bindings often omit annotations.
Scalars
- integers:
i8..i128,u8..u128,isize,usize - floats:
f32,f64 boolchar(Unicode scalar value)
let i: i32 = -42;
let u: u64 = 7;
let f = 3.14_f64;
let b = true;
let c: char = '🚀';
Numeric literals:
let bin = 0b1010; // 10
let hex = 0xFF; // 255
let sep = 1_000_000;
Compounds
- tuples: fixed-size, possibly heterogeneous
- arrays: fixed-size, homogeneous
- slices: views into arrays/Vec
- strings:
String(owned),&str(borrowed)
let tup: (i32, &str) = (42, "answer");
let arr: [i32; 3] = [1, 2, 3];
let sl: &[i32] = &arr[..];
let s: String = String::from("hello");
let r: &str = &s;
Type inference and annotations
Rust infers local types; annotate when needed for clarity or disambiguation.
let x = 1; // inferred i32
let y: i64 = 1; // explicit
let v = vec![1, 2, 3]; // Vec<i32>
Shadowing and mutability
Bindings are immutable by default; use mut to allow reassignment. Shadowing creates a new binding.
let x = 1;
let x = x + 1; // shadow
let mut y = 0;
y += 1;
Ownership preview
Types like String own their data; references &T/&mut T borrow without transferring ownership.
Option and Result
Idiomatic absence and error handling.
let maybe: Option<i32> = None;
let ok: Result<i32, &str> = Ok(42);
Summary
- Scalars and compound types cover most needs; strings are
String/&str - Inference is strong; annotate signatures and when helpful
- Mutability is explicit; shadowing creates new bindings