Actualizando un valor en HashMap en Rust: de principiante a experto

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Cómo actualizar un valor en un HashMap mutable en Rust: de principiante a experto

\n\n

¿Alguna vez te has encontrado con una situación en la que necesitas actualizar un valor en un HashMap en Rust, pero el compilador insiste en no dejar pasar tu código? Si es así, no estás solo. La pregunta "How can I update a value in a mutable HashMap?" en Stack Overflow ha acumulado miles de visitas, lo que significa que incluso los desarrolladores experimentados a veces se confunden con los matices de trabajar con esta colección.

\n\n

En este artículo, analizaremos todas las formas de actualizar valores en un HashMap en Rust: desde el básico insert hasta el avanzado entry().and_modify(). Aprenderás cómo modificar datos correctamente, evitar errores típicos y escribir código idiomático. ¡Allá vamos!

\n\n

¿Por qué actualizar en un HashMap no es simplemente "tomar y cambiar"?

\n\n

A diferencia de muchos lenguajes, Rust te obliga a trabajar explícitamente con la propiedad y el préstamo. Cuando quieres actualizar un valor en un HashMap, necesitas resolver tres tareas:

\n\n
    \n
  • Verificar la existencia de la clave — ¿ya existe ese valor?
  • \n
  • Modificar el valor — si la clave existe, actualizarlo
  • \n
  • Insertar uno nuevo — si la clave no existe, agregarlo
  • \n
\n\n

¿Suena simple? Veamos el código.

\n\n

Método 1: El clásico insert (pero con truco)

\n\n

La forma más directa es usar insert. Este sobrescribe el valor si la clave existe, o inserta un nuevo par si la clave no existe.

\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// Actualizamos el valor para Alice\nscores.insert(String::from("Alice"), 15);\n\nprintln!("{:?}", scores); // {"Alice": 15, "Bob": 20}
\n\n

¿Funciona? Sí. Pero hay un detalle: insert devuelve un Option<V> — el valor anterior, si lo había. Esto es útil si quieres conservar el valor previo. Pero, ¿qué pasa si necesitas actualizar el valor basándote en el anterior? Por ejemplo, ¿incrementar un contador en 1?

\n\n
// Queremos incrementar el puntaje de Alice en 1\nif let Some(score) = scores.get_mut("Alice") {\n    *score += 1;\n}
\n\n

Esto funciona, pero requiere dos operaciones: verificar la existencia y modificar. ¿Y si la clave no existe? Tendrías que hacer una inserción por separado. No es muy elegante.

\n\n

Método 2: Entry API — el rey de las actualizaciones

\n\n

Rust tiene una herramienta poderosa: la Entry API. Permite, en una sola expresión, verificar la existencia de una clave, actualizar o insertar un valor. Esta es la forma idiomática de trabajar con HashMap.

\n\n
use std::collections::HashMap;\n\nlet mut word_count = HashMap::new();\n\n// Contamos palabras en la oración\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

Analicemos la magia:

\n
    \n
  • entry(key) — crea una entrada para la clave
  • \n
  • or_insert(0) — si la clave no existe, inserta el valor 0 y devuelve una referencia mutable a él
  • \n
  • *count += 1 — desreferenciamos la referencia e incrementamos el valor
  • \n
\n\n

¡Voilà! Una sola línea y resolvimos el problema. Pero esto no es todo.

\n\n

Método 3: and_modify — cuando solo necesitas actualizar

\n\n

¿Qué pasa si quieres actualizar el valor solo si la clave existe, y si no, no hacer nada? ¿O insertar un valor diferente? Para eso están and_modify y or_insert en cadena.

\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// Incrementamos la cantidad de manzanas en 1, si existen\ninventory.entry("apples".to_string())\n    .and_modify(|                

Blogs

Book Recommendations