In programming, data types are classifications that tell the compiler or interpreter how the programmer intends to use the data. They specify the kind of values a variable can hold, the operations that can be performed on it, and the amount of memory it occupies. Rust is a statically typed language, meaning that the types of variables must be known at compile time. While Rust often infers types automatically, you can also explicitly annotate them.
Rust categorizes data types into two main sets: Scalar Types and Compound Types.
1. Scalar Types
Scalar types represent a single value. Rust has four primary scalar types:
* Integers: Whole numbers without a fractional component. They come in various sizes and can be signed (can be positive, negative, or zero) or unsigned (can only be non-negative).
* Signed Integers: `i8`, `i16`, `i32`, `i64`, `i128`. The `i` stands for integer, and the number indicates the number of bits it occupies. `i32` is the default.
* Unsigned Integers: `u8`, `u16`, `u32`, `u64`, `u128`. The `u` stands for unsigned. `u32` is a common default for counting.
* Architecture-dependent Integers: `isize` and `usize`. These types depend on the architecture of the computer your program is running on (e.g., 64 bits on a 64-bit architecture, 32 bits on a 32-bit architecture). They are primarily used for indexing collections or for sizes that might vary by platform.
* Integer literals can be suffixed (e.g., `57u8`, `98_222i64`) or use various bases (decimal: `98_222`, hex: `0xff`, octal: `0o77`, binary: `0b1111_0000`, byte `b'A'` (u8 only)).
* Floating-Point Numbers: Numbers with decimal points. Rust has two primitive floating-point types:
* `f32` (single-precision float)
* `f64` (double-precision float). This is the default type because it offers more precision.
* Booleans: Represent truth values. They can only be `true` or `false`. The type is `bool`.
* Characters: Rust's `char` type represents a single Unicode scalar value, meaning it can represent a lot more than just ASCII. Character literals are specified with single quotes (e.g., `'a'`, `'😊'`).
2. Compound Types
Compound types can group multiple values into one type. Rust has two primitive compound types:
* Tuples: A tuple is a general-purpose way of grouping together a number of values with a variety of types into one compound type. Tuples have a fixed length: once declared, they cannot grow or shrink in size.
* Elements can be accessed by their index (e.g., `my_tuple.0`).
* Tuples can be destructured to extract individual values.
* Arrays: An array is a collection of multiple values of the *same* type. Arrays also have a fixed length. Unlike tuples, which can have elements of different types, every element in an array must have the same type. Arrays are allocated on the stack. When you need a collection that can grow or shrink in size, or whose elements might be on the heap, you'd typically use a `Vec<T>` (vector) instead, but `Vec<T>` is not a primitive type.
Example Code
fn main() {
// --- Scalar Types ---
// Integers
let an_integer: i32 = 42; // Explicit type annotation
let inferred_integer = -128; // Rust infers i32 by default for integers not explicitly typed
let big_unsigned: u64 = 1_000_000_000_000; // Underscores for readability
let byte_value: u8 = b'A'; // Byte literal (u8 only)
let hexadecimal = 0xff; // Hexadecimal literal (defaults to i32)
println!("Integers:");
println!(" Explicit i32: {}", an_integer);
println!(" Inferred i32: {}", inferred_integer);
println!(" Big Unsigned u64: {}", big_unsigned);
println!(" Byte value (u8): {}", byte_value);
println!(" Hexadecimal 0xff: {}", hexadecimal);
// Floating-Point Numbers
let x = 2.0; // f64 (default)
let y: f32 = 3.0; // f32
println!("\nFloating-Point Numbers:");
println!(" f64 (default): {}", x);
println!(" f32: {}", y);
// Booleans
let t = true;
let f: bool = false; // Explicit type annotation
println!("\nBooleans:");
println!(" True: {}", t);
println!(" False: {}", f);
// Characters
let c = 'z';
let z: char = 'ℤ'; // Unicode character
let heart_eyes = '😻';
println!("\nCharacters:");
println!(" ASCII char: {}", c);
println!(" Unicode char: {}", z);
println!(" Emoji char: {}", heart_eyes);
// --- Compound Types ---
// Tuples
let tup: (i32, f64, u8) = (500, 6.4, 1);
let (val1, val2, val3) = tup; // Destructuring
println!("\nTuples:");
println!(" Tuple elements via destructuring: {}, {}, {}", val1, val2, val3);
println!(" Accessing by index: first={}, second={}, third={}", tup.0, tup.1, tup.2);
// Arrays
// An array of 5 i32 integers
let a: [i32; 5] = [0, 1, 2, 3, 4];
// An array of 5 'initial' characters, initialized with a repeating value
let b = ['initial'; 5]; // Type inferred as [char; 5]
println!("\nArrays:");
println!(" First element of array 'a': {}", a[0]);
println!(" Second element of array 'b': {}", b[1]);
print!(" Array 'a' elements: ");
for element in a.iter() {
print!("{} ", element);
}
println!();
print!(" Array 'b' elements: ");
for element in b.iter() {
print!("{:?} ", element); // Use {:?} for char arrays due to print! behavior with char
}
println!();
}








Data Types