Module 3 • Lesson 14

Working with Strings

📚 9 min read 💻 Free Course 🦀 nixus.pro

Two String Types

fn main() {
    // &str: immutable slice (often 'static - points to binary)
    let s1: &str = "hello";

    // String: owned, heap-allocated, mutable
    let mut s2 = String::from("hello");
    s2.push(' ');
    s2.push_str("world");
    s2 += "!";
    println!("{}", s2); // "hello world!"

    // format! - safe concatenation, does not move
    let a = String::from("Hello");
    let b = String::from("World");
    let c = format!("{}, {}!", a, b); // a and b still valid
    println!("{}", c);

    // Conversions
    let owned: String = s1.to_string(); // &str -> String
    let slice: &str = &s2;              // String -> &str (deref coercion)

    // Prefer &str in function parameters:
    fn greet(name: &str) { println!("Hello, {}!", name); }
    greet("literal");     // works
    greet(&s2);           // &String -> &str coercion works
}

String Methods and UTF-8

fn main() {
    let text = "  Hello, World!  ";
    println!("{}", text.trim());
    println!("{}", text.to_lowercase());
    println!("{}", text.contains("World"));
    println!("{}", text.replace("World", "Rust"));
    println!("{:?}", text.split(',').collect::>());
    println!("{}", "ha".repeat(3)); // "hahaha"

    // UTF-8 indexing - cannot use s[0]!
    let emoji = "Hello, 🚀!";
    println!("bytes: {}", emoji.len());     // 11 (rocket is 4 bytes)
    println!("chars: {}", emoji.chars().count()); // 9

    // Safe char access:
    let third: Option = emoji.chars().nth(2);
    println!("{:?}", third); // Some('l')

    // Parse strings
    let n: i32 = "42".parse().unwrap();
    let f: f64 = "3.14".parse().unwrap();
    let bad: Result = "oops".parse();
    println!("{} {} {:?}", n, f, bad);

    // Split and rejoin
    let words: Vec<&str> = "one two three".split_whitespace().collect();
    println!("{}", words.join("-")); // "one-two-three"
}

🎯 Practice

  1. Write fn is_palindrome(s: &str) -> bool using chars().collect into Vec, then compare with reversed
  2. Write fn word_frequency(s: &str) -> HashMap<&str, usize> counting occurrences
  3. Write fn title_case(s: &str) -> String capitalizing first letter of each word

🎉 Key Takeaways