Rust's Data Types

Rust is a statically typed language, which means that the type of a variable must be known at compile time. Rust provides a rich set of built-in data types that can be categorized into two main groups: scalar types and compound types.

1. Scalar Types

Scalar types represent a single value. Rust has four primary scalar types:

  • Integer Types: These represent whole numbers and can be signed or unsigned. The size can vary (e.g., i32, u32, i64, u64, etc.).
  • Floating-Point Types: These represent numbers with decimal points. Rust has two floating-point types: f32 (32-bit) and f64 (64-bit).
  • Boolean Type: This type represents a value that can be either true or false. It is denoted as bool.
  • Character Type: This type represents a single Unicode character and is denoted as char. It is 4 bytes in size.

Example of Scalar Types


fn main() {
let integer: i32 = 42; // Signed 32-bit integer
let unsigned_integer: u32 = 42; // Unsigned 32-bit integer
let float: f64 = 3.14; // 64-bit floating point
let boolean: bool = true; // Boolean value
let character: char = 'R'; // Single character

println!("Integer: {}, Unsigned Integer: {}, Float: {}, Boolean: {}, Character: {}",
integer, unsigned_integer, float, boolean, character);
}

2. Compound Types

Compound types can group multiple values into one type. Rust has two main compound types:

  • Tuples: A tuple is a fixed-size collection of values of different types. Tuples are created using parentheses and can be destructured to access individual elements.
  • Arrays: An array is a fixed-size collection of values of the same type. Arrays are created using square brackets and have a constant size.

Example of Tuples


fn main() {
let tuple: (i32, f64, char) = (42, 3.14, 'R'); // A tuple with different types
let (x, y, z) = tuple; // Destructuring the tuple

println!("Tuple values: x = {}, y = {}, z = {}", x, y, z);
}

Example of Arrays


fn main() {
let array: [i32; 5] = [1, 2, 3, 4, 5]; // An array of 5 integers
println!("Array values: {:?}", array); // Output the entire array

// Accessing elements
let first_element = array[0];
println!("The first element is: {}", first_element); // Output: The first element is: 1
}

3. Slices

Slices are a dynamically sized view into a contiguous sequence of elements. They are often used to reference a portion of an array or a vector without taking ownership of the data.

Example of Slices


fn main() {
let array: [i32; 5] = [1, 2, 3, 4, 5];
let slice: &[i32] = &array[1..4]; // A slice of the array

println!("Slice values: {:?}", slice); // Output: Slice values: [2, 3, 4]
}

4. Strings

Rust has two main string types: &str (string slice) and String (owned string). The String type is mutable and can grow as needed, while &str is an immutable reference to a string slice.

Example of Strings


fn main() {
let string_slice: &str = "Hello, Rust!"; // String slice
let mut owned_string: String = String::from("Hello, "); // Owned string

owned_string.push_str("Rust!"); // Appending to the owned string

println!("String Slice: {}", string_slice); // Output: String Slice: Hello, Rust!
println!("Owned String: {}", owned_string); // Output: Owned String: Hello, Rust!
}

5. Conclusion

Rust's data types provide a robust framework for handling various kinds of data. Understanding scalar and compound types, as well as how to work with strings, is essential for effective programming in Rust. By leveraging these data types, you can create efficient and safe applications.