Mapas (std::map)
Nesta página
Um Map em Zolo é uma coleção de pares chave–valor sem ordem garantida.
Importe com use std::Map. Há duas formas de criar mapas: o literal #{} para
dados estáticos e a API Map::new() para construção dinâmica.
Criar, inserir e ler
Map::new() cria um mapa vazio. set(k, v) insere ou sobrescreve; get(k)
retorna o valor ou nil se a chave não existir.
Criação vazia, inserção de tipos mistos, leitura, chave ausente, sobrescrita e len.
// Feature: Map.new / Map.set / Map.get — create and populate an empty map
// When to use: building a map dynamically, without a fixed-size literal.
use std::Map
// Create an empty map.
let m = Map::new()
// Insert key/value pairs.
m.set("name", "Zolo")
m.set("version", "0.1.0")
m.set("stable", false)
// Retrieve.
print(m.get("name")) // expected: Zolo
print(m.get("version")) // expected: 0.1.0
print(m.get("stable")) // expected: false
// Missing key returns nil.
let missing = m.get("author")
print(missing) // expected: nil
// Overwrite — `set` on an existing key updates it.
m.set("version", "0.2.0")
print(m.get("version")) // expected: 0.2.0
// Size.
print(m.len()) // expected: 3
Verificar e remover
has(k) testa a presença sem consumir o valor; remove(k) deleta a chave —
operar em chave inexistente é seguro.
Contagem de palavras com has/set em loop; remove idempotente.
// Feature: Map.has / Map.remove — testing and removing keys
// When to use: invalidating entries, counting before mutating, avoiding nil.
use std::Map
let cfg = Map::new()
cfg.set("host", "localhost")
cfg.set("port", "8080")
cfg.set("debug", "true")
// has — true/false.
print(cfg.has("host")) // expected: true
print(cfg.has("missing")) // expected: false
// remove — deletes the key.
cfg.remove("debug")
print(cfg.has("debug")) // expected: false
print(cfg.len()) // expected: 2
// remove on a missing key is safe (no-op).
cfg.remove("no-such-key")
print(cfg.len()) // expected: 2
// Pattern: increment a counter while checking for existence.
let counter = Map::new()
let words = ["foo", "bar", "foo", "baz", "foo"]
for w in words {
if counter.has(w) {
counter.set(w, counter.get(w) + 1)
} else {
counter.set(w, 1)
}
}
print(counter.get("foo")) // expected: 3
print(counter.get("bar")) // expected: 1
Chaves, valores e entradas
keys(), values() e entries() retornam arrays. Use Map::from(#{...})
para envolver um literal e usar esses métodos.
Soma de valores via reduce; filtragem de chaves por inicial com filter.
// Feature: Map.keys / Map.values / Map.entries — extracting contents
// When to use: serializing, counting, transforming the whole map at once.
use std::Map
use std::Array
// `#{...}` is a plain map literal — build a Map object with Map.from.
let scores = Map::from(#{math: 95, science: 87, english: 92})
// keys — array with the keys (order not guaranteed).
let keys = scores.keys()
print(keys.len()) // expected: 3
// values — array with the values.
let vals = scores.values()
print(vals.len()) // expected: 3
// entries — array of [key, value] pairs.
let pairs = scores.entries()
print(pairs.len()) // expected: 3
// Each entry is [k, v]. Check a known entry.
print(scores.get("math")) // expected: 95
// Sum the values via reduce.
let total = scores.values().reduce(|acc, x| acc + x, 0)
print(total) // expected: 274
// Number of keys starting with a vowel.
let starts_vowel = scores.keys().filter(|k| {
let c = k.chars()[0]
return c == "a" || c == "e" || c == "i" || c == "o" || c == "u"
})
print(starts_vowel.len()) // expected: 1
Iteração
Há três formas equivalentes de percorrer um mapa: for k in m.keys(),
m.each(|k, v| ...) e for entry in m.entries().
As três formas de iteração lado a lado; ordem de chaves não é garantida.
// Feature: Iterating over a Map — `for` over keys, or Map.each
// When to use: walking through all pairs to print, validate, etc.
use std::Map
// `#{...}` is a plain table literal — wrap with Map.from to use Map.*.
let user = Map::from(#{name: "Alice", age: 30, active: true})
// Form 1: iterate through the keys and index in.
for k in user.keys() {
let v = user.get(k)
print("{k} = {v}")
}
// (key order is not guaranteed)
print("---")
// Form 2: m.each(fn) — receives k, v.
user.each(|k, v| print("each: {k} = {v}"))
print("---")
// Form 3: iterate through entries (array of pairs).
for entry in user.entries() {
let k = entry[0]
let v = entry[1]
print("entry: {k} = {v}")
}
Literal #{} versus API procedural
O literal #{chave: valor} é o atalho para dados fixos. Prefira Map::new()
quando as chaves ou valores vierem de variáveis em tempo de execução. Para
misturar os dois, envolva o literal com Map::from.
Acesso por ponto (.name) e por colchetes; chaves não-identificadores ("user-id"); Map::from para mutação pós-literal.
// Feature: Map literal `#{...}` vs procedural API `Map::new() + Map.set`
// When to use: literal for known data, API for dynamic construction.
use std::Map
// ── Literal — concise, ideal for static data ─────────────────
let user = #{name: "Alice", age: 30, active: true}
print(user["name"]) // expected: Alice
print(user["age"]) // expected: 30
// Dot access when the key is a valid identifier.
print(user.name) // expected: Alice
print(user.active) // expected: true
// Bracket always works — required for non-identifier keys.
let labels = #{"user-id": 42, "x-trace": "abc"}
print(labels["user-id"]) // expected: 42
print(labels["x-trace"]) // expected: abc
// ── Procedural — required for runtime construction ───────────
let m = Map::new()
let names = ["alice", "bob", "carol"]
for name in names {
m.set(name, name.len())
}
print(m.get("alice")) // expected: 5
print(m.get("carol")) // expected: 5
print(m.len()) // expected: 3
// ── Mix — start from a literal and mutate later ──────────────
// Wrap the literal with Map.from so the Map.* helpers (which expect
// the Map shape with `__data` / `__size`) keep working.
let cfg = Map::from(#{host: "localhost", port: 8080})
cfg.set("debug", true)
print(cfg.has("debug")) // expected: true
print(cfg.len()) // expected: 3
Desafio
Dado um array de strings, construa um mapa {palavra: comprimento} usando
Map::new() e um for. Depois use keys() e filter para listar apenas
as palavras com comprimento maior que 4.
Veja também