Rust Tutorial menu

Rust Strings, Vectors and HashMaps

Rust's standard library gives you growable collections: String for text, Vec for lists and HashMap for key and value pairs.

String and &str

Rust has two main text types:

TypeWhat it isExample
&strA borrowed piece of text, often fixed"Lahore"
StringAn owned text that can growString::from("Lahore")

Text in double quotes is a &str. Turn it into a String with String::from() or .to_string().

Example

rust
fn main() {
    let mut msg = String::from("Hello");
    msg.push_str(", Karachi");
    msg.push('!');
    println!("{}", msg);
    println!("{}", msg.len());
    println!("{}", msg.to_uppercase());
    println!("{}", msg.contains("Kar"));
    println!("{}", msg.replace("Hello", "Salam"));

    let first = String::from("Ali");
    let last = "Khan";
    let full = format!("{} {}", first, last);
    println!("{}", full);
}
Output
Hello, Karachi!
15
HELLO, KARACHI!
true
Salam, Karachi!
Ali Khan

format! works like println! but returns a String instead of printing it.

Write function parameters as &str instead of &String. A &str parameter accepts both text literals and borrowed String values.

Splitting and Characters

Example

rust
fn main() {
    let line = "rice,daal,tea";
    for item in line.split(',') {
        println!("{}", item);
    }

    let word = "Rust";
    for c in word.chars() {
        print!("{} ", c);
    }
    println!();
    println!("{}", "  trim me  ".trim());
}
Output
rice
daal
tea
R u s t 
trim me

Vectors

A Vec<T> is a list that can grow. The vec! macro creates one quickly.

Example

rust
fn main() {
    let mut marks = vec![70, 85];
    marks.push(92);
    marks.push(60);
    println!("{:?}", marks);
    println!("Count: {}", marks.len());
    println!("First: {}", marks[0]);

    let last = marks.pop();
    println!("{:?}", last);

    let total: i32 = marks.iter().sum();
    println!("Total: {}", total);

    for m in &marks {
        println!("Mark: {}", m);
    }

    match marks.get(10) {
        Some(m) => println!("Found {}", m),
        None => println!("No mark at index 10"),
    }
}
Output
[70, 85, 92, 60]
Count: 4
First: 70
Some(60)
Total: 247
Mark: 70
Mark: 85
Mark: 92
No mark at index 10
  • marks[10] would crash the program. marks.get(10) returns an Option instead, which is safer.
  • for m in &marks borrows the vector, so you can still use marks after the loop.

HashMap

A HashMap stores values by key. You need to import it with use.

Example

rust
use std::collections::HashMap;

fn main() {
    let mut prices = HashMap::new();
    prices.insert("Samosa", 40);
    prices.insert("Chai", 60);
    prices.insert("Chai", 70);

    println!("{}", prices.len());

    if let Some(p) = prices.get("Chai") {
        println!("Chai costs Rs {}", p);
    }

    match prices.get("Pizza") {
        Some(p) => println!("Pizza costs Rs {}", p),
        None => println!("Pizza is not on the menu"),
    }

    let mut counts = HashMap::new();
    for word in "a b a c a".split(' ') {
        *counts.entry(word).or_insert(0) += 1;
    }
    println!("a appears {} times", counts["a"]);
}
Output
2
Chai costs Rs 70
Pizza is not on the menu
a appears 3 times

Inserting the same key twice replaces the old value. entry().or_insert() adds a key only if it is missing, which is perfect for counting.

A HashMap has no fixed order. Looping over it may give the keys in any order.

Exercise

Exercise

Which call adds the number 5 to the end of let mut v = vec![1, 2];?

Learn Rust with a teacher

Join the Python Programming course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp