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".to_string(), 207);
    page_counts.insert("Grimms' Fairy Tales".to_string(), 751);
    page_counts.insert("Pride and Prejudice".to_string(), 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.to_string()).or_insert(0);
        *page_count += 1;
    }

    println!("{page_counts:#?}");
}
  • 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?
  • This type has several “method-specific” return types, such as std::collections::hash_map::Keys. These types often appear in searches of the Rust docs. Show students the docs for this type, and the helpful link back to the keys method.