Atualizando valor em HashMap no Rust: do iniciante ao profissional

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Como atualizar valor em um HashMap mutável no Rust: do iniciante ao profissional

\n\n

Você já se deparou com uma situação em que precisava atualizar um valor em HashMap no Rust, mas o compilador insistentemente não aceitava seu código? Se sim — você não está sozinho. A pergunta "How can I update a value in a mutable HashMap?" no Stack Overflow acumulou milhares de visualizações, e isso significa que até desenvolvedores experientes às vezes se confundem com as nuances de trabalhar com esta coleção.

\n\n

Neste artigo, vamos analisar todas as formas de atualizar valores em HashMap no Rust: desde o básico insert até o avançado entry().and_modify(). Você aprenderá como modificar dados corretamente, evitar erros típicos e escrever código idiomático. Vamos lá!

\n\n

Por que atualizar em HashMap não é simplesmente "pegar e trocar"?

\n\n

Ao contrário de muitas linguagens, o Rust obriga você a trabalhar explicitamente com posse e empréstimo. Quando você quer atualizar um valor em HashMap, precisa resolver três tarefas:

\n\n
    \n
  • Verificar a existência da chave — já existe esse valor?
  • \n
  • Alterar o valor — se a chave existir, atualizá-la
  • \n
  • Inserir novo — se a chave não existir, adicioná-la
  • \n
\n\n

Parece simples? Vamos ver o código.

\n\n

Método 1: O clássico insert (mas com um truque)

\n\n

A forma mais direta é usar insert. Ele sobrescreve o valor se a chave existir, ou insere um novo par se a chave não existir.

\n\n
use std::collections::HashMap;\n\nlet mut scores = HashMap::new();\nscores.insert(String::from("Alice"), 10);\nscores.insert(String::from("Bob"), 20);\n\n// Atualizando o valor para Alice\nscores.insert(String::from("Alice"), 15);\n\nprintln!("{:?}", scores); // {"Alice": 15, "Bob": 20}
\n\n

Funciona? Sim. Mas há um detalhe: insert retorna Option<V> — o valor antigo, se existir. Isso é útil se você quiser preservar o valor anterior. Mas e se você precisar atualizar o valor com base no antigo? Por exemplo, aumentar a pontuação em 1?

\n\n
// Queremos aumentar a pontuação da Alice em 1\nif let Some(score) = scores.get_mut("Alice") {\n    *score += 1;\n}
\n\n

Isso funciona, mas requer duas operações: verificação de existência e alteração. E se a chave não existir? Você terá que fazer a inserção separadamente. Não é muito elegante.

\n\n

Método 2: Entry API — o rei das atualizações

\n\n

O Rust tem uma ferramenta poderosa — a Entry API. Ela permite, em uma única expressão, verificar a existência da chave, atualizar ou inserir o valor. Esta é a forma idiomática de trabalhar com HashMap.

\n\n
use std::collections::HashMap;\n\nlet mut word_count = HashMap::new();\n\n// Contando palavras na frase\nfor word in "hello world hello Rust".split_whitespace() {\n    let count = word_count.entry(word.to_string()).or_insert(0);\n    *count += 1;\n}\n\nprintln!("{:?}", word_count);\n// {"hello": 2, "world": 1, "Rust": 1}
\n\n

Vamos analisar a mágica:

\n
    \n
  • entry(key) — cria uma entrada para a chave
  • \n
  • or_insert(0) — se a chave não existir, insere o valor 0 e retorna uma referência mutável a ele
  • \n
  • *count += 1 — desreferencia a referência e incrementa o valor
  • \n
\n\n

Voilà! Uma linha — e resolvemos o problema. Mas isso não é tudo.

\n\n

Método 3: and_modify — quando você só precisa atualizar

\n\n

E se você quiser atualizar o valor apenas se a chave existir, e se não existir — não fazer nada? Ou inserir um valor diferente? Para isso existem and_modify e or_insert em cadeia.

\n\n
use std::collections::HashMap;\n\nlet mut inventory = HashMap::new();\ninventory.insert("apples".to_string(), 10);\ninventory.insert("bananas".to_string(), 5);\n\n// Aumentando a quantidade de maçãs em 1, se existirem\ninventory.entry("apples".to_string())\n    .and_modify(|                

Blogs

Book Recommendations