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.isize
andusize
are pointer-sized integers (likeptrdiff_t
andsize_t
in C). - Floating-Point:
f32
(single-precision) andf64
(double-precision). - Boolean:
bool
(can betrue
orfalse
). - Character:
char
represents 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.