Data Types
Scalar Data Types
Type Family | Types | Examples |
---|---|---|
Signed Integers | i8 ⮳, i16 ⮳, i32 ⮳, i64 ⮳, i128 ⮳, isize ⮳. | -8i8 , -32i32 . |
Unsigned Integers | u8 ⮳, u16 ⮳, u32 ⮳, u64 ⮳, u128 ⮳, usize ⮳. | 6u8 . |
Floating point | f32 ⮳, f64 ⮳. | 0.15 . |
Boolean | bool ⮳. | true , false . |
Unicode Character | char ⮳ | let z: char = 'ℤ'; |
Unit | unit ⮳. | The () type (aka void in other languages) has exactly one value () , and is used when there is no other meaningful value that could be returned. |
Never | never ⮳. | ! represents the type of computations which never resolve to any value at all. For example, the exit function fn exit(code: i32) -> ! exits the process without ever returning, and so returns ! . |
usize
⮳ and isize
⮳ are 32 or 64 bits, depending on the architecture of the computer.
fn main() { // Integer types let a: i8 = -128; // 8-bit signed integer let b: u8 = 255; // 8-bit unsigned integer let c: i16 = 32767; // 16-bit signed integer let d: u16 = 65535; // 16-bit unsigned integer let e: i32 = 2147483647; // 32-bit signed integer (default for integers) let f: u32 = 4294967295; // 32-bit unsigned integer let g: i64 = 9223372036854775807; // 64-bit signed integer let h: u64 = 18446744073709551615; // 64-bit unsigned integer let i: i128 = 170141183460469231731687303715884105727; // 128-bit signed integer let j: u128 = 340282366920938463463374607431768211455; // 128-bit unsigned integer let k: isize = 9223372036854775807; // pointer-sized signed integer (depends on architecture) let l: usize = 18446744073709551615; // pointer-sized unsigned integer (depends on architecture) // Type inference let m = 42; // Compiler infers i32 by default // Floating-point types let n: f32 = 3.1; // 32-bit float let o: f64 = 2.7; // 64-bit float (default for floats) // Boolean type let p: bool = true; let q: bool = false; // Character type (Unicode scalar value) let r: char = 'a'; let s: char = '😀'; // Unicode emoji let t: char = '∞'; // Unicode symbol // String types let u: &str = "Hello"; // String slice let v: String = String::from("World"); // Owned string // Print all values println!("Integers:"); println!("i8: {}", a); println!("u8: {}", b); println!("i16: {}", c); println!("u16: {}", d); println!("i32: {}", e); println!("u32: {}", f); println!("i64: {}", g); println!("u64: {}", h); println!("i128: {}", i); println!("u128: {}", j); println!("isize: {}", k); println!("usize: {}", l); println!("inferred i32: {}", m); println!("\nFloating-point:"); println!("f32: {}", n); println!("f64: {}", o); println!("\nBooleans:"); println!("true: {}", p); println!("false: {}", q); println!("\nCharacters:"); println!("ASCII: {}", r); println!("Emoji: {}", s); println!("Symbol: {}", t); println!("\nStrings:"); println!("String slice: {}", u); println!("Owned string: {}", v); // Type operations println!("\nType operations:"); println!( "Integer addition: {} + {} = {}", a, 100, a.wrapping_add(100) ); // Using wrapping_add to avoid overflow panic println!("Float multiplication: {} * {} = {}", n, o, (n as f64) * o); println!("Boolean AND: {} && {} = {}", p, q, p && q); println!("Boolean OR: {} || {} = {}", p, q, p || q); println!( "String concatenation: {} + {} = {}", u, v, u.to_string() + &v ); }
Handle Overflows
- Wrap in all modes with the
wrapping_*
methods, such aswrapping_add
⮳. - Return the
std::option::Option::None
⮳ value if there is overflow with thechecked_*
methods. - Return the value and a boolean indicating whether there was overflow with the
overflowing_*
methods. - Saturate at the value's minimum or maximum values with the
saturating_*
methods.
Compound Data Types: Tuples and Arrays
Compound types can group multiple values into one type. Rust has two primitive compound types: tuples and arrays.
Type | Examples |
---|---|
Tuples | let tup: (i32, f64, u8) = (500, 6.4, 1); . Access via let five_hundred = x.0; . Destructuring via let (x, y, z) = tup; . |
Arrays | let a: [i32; 5] = [1, 2, 3, 4, 5]; allocated on the stack. Access via let first = a[0]; . |
A Vector is a similar collection type provided by the standard library that is allowed to grow or shrink in size.
fn main() { println!("=== TUPLES ==="); // Declaring a tuple with mixed types let person: (String, i32, bool) = (String::from("Alice"), 30, true); // Accessing tuple elements by index println!("Name: {}", person.0); println!("Age: {}", person.1); println!("Active: {}", person.2); // Destructuring a tuple let (name, age, active) = person; println!( "Destructured - Name: {}, Age: {}, Active: {}", name, age, active ); // Nested tuples let complex_data = (("Coordinates", (10.5, 20.8)), 42, [1, 2, 3]); println!( "Nested tuple access: {}, {}", (complex_data.0).0, (complex_data.0).1.0 ); // Unit (empty tuple) let empty: () = (); println!("Empty tuple: {:?}", empty); // Tuple with a single element let single = (42,); // Note the comma println!("Single element tuple: {:?}", single); println!("\n=== ARRAYS ==="); // Fixed-size array with explicit type let numbers: [i32; 5] = [1, 2, 3, 4, 5]; // Array with repeated values let _zeros = [0; 10]; // Creates [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] // Accessing array elements println!("First element: {}", numbers[0]); // Starts at zero println!("Last element: {}", numbers[4]); // Getting array length println!("Array length: {}", numbers.len()); // Array slices let slice = &numbers[1..4]; // [2, 3, 4] println!("Slice: {:?}", slice); // Array of tuples let pairs: [(i32, &str); 3] = [(1, "one"), (2, "two"), (3, "three")]; // Iterating over an array println!("Iterating over array:"); for num in numbers.iter() { println!(" Value: {}", num); } // Iterating with index println!("Iterating with index:"); for (i, num) in numbers.iter().enumerate() { println!(" numbers[{}] = {}", i, num); } // Iterating over array of tuples println!("Iterating over array of tuples:"); for (number, name) in pairs.iter() { println!(" {} is written as {}", number, name); } // Multi-dimensional array let matrix: [[i32; 3]; 2] = [[1, 2, 3], [4, 5, 6]]; println!("Multi-dimensional array:"); for row in matrix.iter() { println!(" {:?}", row); } // Mutating arrays let mut mutable_array = [1, 2, 3, 4, 5]; mutable_array[2] = 99; println!("Mutated array: {:?}", mutable_array); // Functions with tuples fn swap_tuple(tuple: (i32, i32)) -> (i32, i32) { (tuple.1, tuple.0) } let original = (10, 20); let swapped = swap_tuple(original); println!("\nOriginal tuple: {:?}", original); println!("Swapped tuple: {:?}", swapped); }
Type Aliases
Use the type
keyword to declare type aliases: type Kilometers = i32;
.
Related Topics
See also:
- Enums.
- Option.
- Result.
- Slices.
- Strings.
- Structs.
- Vectors.
- Data Structures.