HashMap

Hash map (Mapa de hash) padrão com proteção contra ataques HashDoS:

use std::collections::HashMap;

fn main() {
    let mut page_counts = HashMap::new();
    page_counts.insert("Adventures of Huckleberry Finn", 207);
    page_counts.insert("Grimms' Fairy Tales", 751);
    page_counts.insert("Pride and Prejudice", 303);

    if !page_counts.contains_key("Les Misérables") {
        println!(
            "Nós sabemos sobre livros {}, mas não Les Misérables.",
            page_counts.len()
        );
    }

    for book in ["Pride and Prejudice", "Alice's Adventure in Wonderland"] {
        match page_counts.get(book) {
            Some(count) => println!("{book}: {count} páginas"),
            None => println!("{book} é desconhecido."),
        }
    }

    // Use o método .entry() para inserir um valor caso nada seja encontrado.
    for book in ["Pride and Prejudice", "Alice's Adventure in Wonderland"] {
        let page_count: &mut i32 = page_counts.entry(book).or_insert(0);
        *page_count += 1;
    }

    println!("{page_counts:#?}");
}
This slide should take about 5 minutes.
  • HashMap não está definido no prelúdio e precisa ser incluído no escopo.

  • Tente as seguintes linhas de código. A primeira linha verá se um livro está no hash map e, caso não esteja, retorna um valor alternativo. A segunda linha irá inserir o valor alternativo no hash map se o livro não for encontrado.

    let pc1 = page_counts
        .get("Harry Potter and the Sorcerer's Stone")
        .unwrap_or(&336);
    let pc2 = page_counts
        .entry("The Hunger Games".to_string())
        .or_insert(374);
  • Ao contrário de vec!, infelizmente não existe uma macro hashmap! padrão.

    • Entretanto, desde o Rust 1.56, o HashMap implementa From<[(K, V); N]>, o que nos permite inicializar facilmente um hash map a partir de uma matriz literal:

      let page_counts = HashMap::from([
        ("Harry Potter and the Sorcerer's Stone".to_string(), 336),
        ("The Hunger Games".to_string(), 374),
      ]);
  • Alternativamente, o HashMap pode ser construído a partir de qualquer Iterator que produz tuplas de chave-valor.

  • Estamos mostrando HashMap<String, i32>, e evite usar &str como chave para facilitar os exemplos. É claro que o uso de referências em coleções pode ser feito, mas isto pode levar a complicações com o verificador de empréstimos.

    • Tente remover to_string() do exemplo acima e veja se ele ainda compila. Onde você acha que podemos ter problemas?
  • Este tipo tem vários tipos de retorno “específicos do método”, como std::collections::hash_map::Keys. Esses tipos geralmente aparecem em pesquisas nos documentos do Rust. Mostre aos alunos os documentos para este tipo e o link útil de volta ao método keys.