Heroes / Esempi / 10-maps

examples/gallery/10-maps.hero

La ricerca in una mappa restituisce un valore oppure un errore se la chiave manca.

Una mappa associa chiavi a valori. m[k] cerca la chiave k e restituisce un V?: un valore di tipo V oppure un errore. Quando leggi il risultato, devi quindi gestire anche il caso in cui la chiave non esiste.

Eseguilo

$ heroes run examples/gallery/10-maps.hero

Questo esempio serve a illustrare il linguaggio. Qui trovi il programma e non un risultato: non ci sono ancora test che confrontino il suo output byte per byte.

Il programma

## Maps, and absence as a type
#
# `m[k]` does not return a `V`. It returns a `V?`, because the key might not
# be there — so the compiler makes you say what happens when it isn't. There
# is no null to forget to check.

# The four ways to read a `V?`, on one line each (§4.6).
function score_of(scores: {str: i64}, name: str) -> i64
    return scores[name].default(0)

function known(scores: {str: i64}, name: str) -> bool
    return !scores[name].is_err()

# `.is_err()` asks without extracting; the `match` extracts without aborting.
function report(scores: {str: i64}, name: str) -> str
    got = scores[name]

    if got.is_err()
        return name + " has no score"
    return name + " scored " + got.must().to_str()

# The general way, and the only one that names the error: `match` on `.ok`/`.err`.
function describe(scores: {str: i64}, name: str) -> str
    return match scores[name]
        .ok v  => v.to_str()
        .err e => e.code

# A map is built as a literal. There is no insert in the built-in inventory
# (§4.20) — `push` is for arrays — so this table is written, not accumulated.
function table() -> {str: i64}
    return {"ada": 10, "grace": 9, "alan": 8}

function total_of(scores: {str: i64}, names: [str]) -> i64
    sum: i64 @= 0

    for name in names
        sum @ sum + score_of(scores, name)

    return sum

test "a missing key is a type, not a crash"
    scores = table()
    assert score_of(scores, "ada") == 10
    assert score_of(scores, "nobody") == 0
    assert known(scores, "grace")
    assert known(scores, "nobody") == false
    assert scores.len() == 3

test "the four readings agree about presence and disagree about absence"
    scores = table()
    assert report(scores, "alan") == "alan scored 8"
    assert report(scores, "nobody") == "nobody has no score"
    assert describe(scores, "alan") == "8"

    # The spec names it now — `m[k]` returns a `V?` with code `missing_key` — so
    # this asserts it. It used to say the code was unspecified and assert only
    # that *something* came back, which was right on the day it was written and
    # became a comment contradicting the spec the moment the silence closed
    # (panel 034 R5: a document asserting something the compiler does not do).
    assert describe(scores, "nobody") == "missing_key"

function main()
    print(total_of(table(), ["ada", "grace", "nobody"]))
examples/gallery/10-maps.hero, 63 righe

impronta sha256 d29a9dd0d223 · 1 file · index.json

Successivo: 11-trees. Tutti gli esempi. ← Precedente: 09-holes

Eseguine uno: i quattro comandi. Impara il linguaggio, oppure leggi la specifica completa in un solo file.