HashMap

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

use std::collections::HashMap;

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

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

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

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

    println!("{contadores_paginas:#?}");
}
  • 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 = contadores_paginas
          .get("Harry Potter and the Sorcerer's Stone ")
          .unwrap_or(&336);
      let pc2 = contadores_paginas
          .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 contadores_paginas = 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.