How do I safely get a value from a Dict when the key might not exist?
← Safe Value Access · Ref: Q161
EK9 Dicts use getOrDefault(key, default) for safe value access. There is no .get() method that could return an unset value. This design eliminates null pointer exceptions from dictionary lookups.
GETORDEFAULT
Always returns a usable value:
age <- ages.getOrDefault("Alice", 0)
If the key exists, returns its value. If missing, returns the default you provide. No exceptions, no unset results.
CONTAINS CHECK
Test for key existence before access:
if ages contains "Alice" stdout.println("Alice is in the dict")
The contains operator checks keys, not values.
GUARD PATTERN WITH FOR
Iterate safely over entries without worrying about missing keys:
for entry in ages stdout.println(`${entry.key()}: ${entry.value()}`)
Every entry yielded by iteration is guaranteed to be set.
IS IN / IS NOT IN
Natural language syntax for key checks:
if "Bob" is in ages stdout.println("Found Bob") if "Zara" is not in ages stdout.println("Zara not found")
See Q46 for Dict basics. See Q90 for Dict operations. See Q129 for missing key patterns. See Q165 for why EK9 has no .get() method. See Q243 for coalescing operators (??, ?:, <?, >?) used for safe value selection.
Example
defines module qa.safeaccess.dictsafe defines program DictSafeAccessDemo() stdout <- Stdout() ages <- {"Alice": 30, "Bob": 25, "Charlie": 35} // === GETORDEFAULT === // Key exists — returns actual value aliceAge <- ages.getOrDefault("Alice", 0) stdout.println(`Alice age: ${aliceAge}`) // Key missing — returns default missingAge <- ages.getOrDefault("Zara", 0) stdout.println(`Missing age (default 0): ${missingAge}`) // === CONTAINS CHECK === if ages contains "Alice" stdout.println("Alice is in the dict") if ages contains "Unknown" stdout.println("Should not print") // === IS IN / IS NOT IN === if "Bob" is in ages stdout.println("Found Bob") if "Zara" is not in ages stdout.println("Zara not found") // === SAFE ITERATION === // Every entry from iteration is guaranteed set for entry in ages stdout.println(`${entry.key()}: ${entry.value()}`) // === COMBINING PATTERNS === // Use getOrDefault for computation with fallback score <- ages.getOrDefault("Dave", -1) stdout.println(`Dave score (or -1): ${score}`)
Common mistakes
E50060 — Dict has no get() method that could return an unset value. Use getOrDefault(key, default) which always returns a usable value. This prevents null/unset bugs from missing key lookups. See ek9 -h E50060 for details.
Incorrect:
aliceAge <- ages.get("Alice")
Correct:
aliceAge <- ages.getOrDefault("Alice", 0)
E50060 — Dict has no getValue() method. Use getOrDefault(key, default) which always returns a usable value. See ek9 -h E50060 for details.
Incorrect:
score <- ages.getValue("Dave")
Correct:
score <- ages.getOrDefault("Dave", -1)
Other ways to ask this
- How do I avoid exceptions when accessing a Dict key in EK9?
- What is the safe way to look up a Dict value in EK9?
- How do I handle missing Dict keys in EK9?
Coming from another language?
Java: map.get(key) returns null if missing (NPE risk), map.getOrDefault(key, default) exists but is rarely used. Python: dict[key] throws KeyError, dict.get(key, default) is the safe alternative. Rust: HashMap.get() returns Option, must unwrap or match. Go: val, ok := m[key] comma-ok idiom, zero value if missing. Kotlin: map[key] returns null, map.getOrDefault() available. EK9: only getOrDefault() exists, no .get() that could return unset, contains for key checks.
Keywords: contains, dict, null, access, null-safe, exception, key, missing, getOrDefault, default, safe, lookup, guard