Rust Collections

Vectors, Arrays, and Slices

Vectors:

Vectors (Vec) are growable arrays. They can change size, making them more flexible than fixed-size arrays.

Example:

                    
fn main() {
    let mut v: Vec = Vec::new(); // Create an empty vector
    v.push(1);
    v.push(2);
    v.push(3);

    for i in &v {
        println!("{}", i);
    }

    // Another way to create a vector
    let v2 = vec![1, 2, 3, 4, 5];
    println!("{:?}", v2);
}
                    
                  

Arrays:

Arrays are static collections of elements of single type. The size must be known by compile time.

Example:

                    
fn main() {
    let a = [1, 2, 3, 4, 5]; // Array with 5 elements

    for i in &a {
        println!("{}", i);
    }

    println!("First element: {}", a[0]);
    println!("Array length: {}", a.len());
}
                    
                  

Slices:

A slice is an object that is a sub-sequence of a collection, like an array or vector. Slices give you the ability to view and edit certain aspects of a gathering without actually owning them.

Example:

                    
fn main() {
    let a = [1, 2, 3, 4, 5];
    let slice = &a[1..3]; // Slice containing elements at index 1 and 2

    println!("Slice: {:?}", slice);
}
                    
                  

Strings and String Manipulation

Rust has two main string types: String and &str.

String:

String is a growable, heap-allocated string type.

Example:

                    
fn main() {
    let mut s = String::from("Hello");
    s.push_str(", world!"); // Append a string slice
    s.push('!'); // Append a character

    println!("{}", s);
}
                    
                  

&str:

&str is an immutable string slice, usually seen as a reference to a part of a String.

Example:

                    
fn main() {
    let s = "Hello, world!"; // &str type

    println!("{}", s);
}
                    
                  

String Manipulation:

Rust provides various methods for string manipulation.

Example:

                    
fn main() {
    let s1 = String::from("Hello, ");
    let s2 = String::from("world!");

    let s3 = s1 + &s2; // s1 is moved and can no longer be used
    println!("{}", s3);

    let s4 = format!("{} {}", "Hello", "world!");
    println!("{}", s4);
}
                    
                  

HashMaps and Other Collection Types

HashMaps:

HashMap<K, V> is a key-value set. Types keys and values may implement the traits Eq and Hash.

Example:

                    
use std::collections::HashMap;

fn main() {
    let mut scores = HashMap::new();

    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Yellow"), 50);

    let team_name = String::from("Blue");
    let score = scores.get(&team_name);
    match score {
        Some(&score) => println!("Score: {}", score),
        None => println!("No score found"),
    }

    for (key, value) in &scores {
        println!("{}: {}", key, value);
    }
}
                    
                  

Other Collection Types:

  • VecDeque: A queue that can be accessed from either end and allows you to add or remove elements at either end.
  • LinkedList: A doubly linked list.
  • HashSet: A set of unique values.
  • BinaryHeap: A binary heap (priority queue).

Example with HashSet:

                    
use std::collections::HashSet;

fn main() {
    let mut books = HashSet::new();

    books.insert(String::from("The Hobbit"));
    books.insert(String::from("1984"));
    books.insert(String::from("The Catcher in the Rye"));

    if !books.contains("Moby Dick") {
        println!("We need Moby Dick");
    }

    books.remove("1984");

    for book in &books {
        println!("{}", book);
    }
}
                    
                  

Summary

  • Vectors: Dynamic, heap-allocated arrays of expandable size.
  • Arrays: Fixed-size, stack-allocated collections.
  • Slices: References to a contiguous sequence of elements within a collection.
  • HashMaps: Key-value stores for efficient lookups.

The Rust collection types with their flexible and efficient nature, are therefore useful in managing and manipulating data which different programming needs.