2.5 Data Types and Annotations
Rust is a statically typed language, meaning the type of every variable must be known at compile time. The compiler can often infer the type, but you can also provide explicit type annotations. Once assigned, a variable’s type cannot change.
2.5.1 Primitive Data Types
Rust offers a standard set of primitive types:
- Integers: Signed (
i8,i16,i32,i64,i128,isize) and unsigned (u8,u16,u32,u64,u128,usize). The number indicates the bit width.isizeandusizeare pointer-sized integers (likeptrdiff_tandsize_tin C). - Floating-Point:
f32(single-precision) andf64(double-precision). - Boolean:
bool(can betrueorfalse). - Character:
charrepresents a Unicode scalar value (4 bytes), capable of holding characters like ‘a’, ‘國’, or ‘😂’. This contrasts with C’schar, which is typically a single byte.
2.5.2 Type Inference
The compiler can often deduce the type based on the assigned value and context.
fn main() { let answer = 42; // Type i32 inferred by default for integers let pi = 3.14159; // Type f64 inferred by default for floats let active = true; // Type bool inferred println!("answer: {}, pi: {}, active: {}", answer, pi, active); }
2.5.3 Explicit Type Annotation
Use a colon : after the variable name to specify the type explicitly, which is necessary when the compiler needs guidance or you want a non-default type (e.g., f32 instead of f64).
fn main() { let count: u8 = 10; // Explicitly typed as an 8-bit unsigned integer let temperature: f32 = 21.5; // Explicitly typed as a 32-bit float println!("count: {}, temperature: {}", count, temperature); }
2.5.4 Comparison with C
In C, basic types like int can have platform-dependent sizes. C99 introduced fixed-width integer types in <stdint.h> (e.g., int32_t, uint8_t), which correspond directly to Rust’s integer types. C lacks built-in type inference like Rust’s.