Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Match literal values

A pattern can be an integer, string, or boolean literal. It matches a value equal to it, so match also selects on an integer, a str, or a bool directly, and on such a value inside an enum payload:

enum Command:
    Move(i64)
    Say(str)

def opcode(name: str) -> i64:
    match name:
        case "cpy":
            1
        case "inc" | "dec":
            2
        case _:
            0

def describe(command: Command) -> str:
    match command:
        case Command.Move(0):
            "stay"
        case Command.Move(_):
            "move"
        case Command.Say("" | "..."):
            "silence"
        case Command.Say(words):
            words

def main() -> Result[(), IoError]:
    print(opcode("cpy"))?
    print(opcode("dec"))?
    print(opcode("jmp"))?
    print(describe(Command.Move(0)))?
    print(describe(Command.Move(3)))?
    print(describe(Command.Say("...")))?
    print(describe(Command.Say("hello")))?
    Ok(())
1
2
0
stay
move
silence
hello

Cases are tried in order. Literals cannot name every integer or string, so such a match ends with case _:, and a payload position needs _ or a name after its literals:

def main() -> Result[(), IoError]:
    count = 3
    match count:
        case 1:
            print("one")?
    Ok(())
non-exhaustive match; cases cannot name every i64 value, so end with `case _:`

True and False together cover a bool, so no case _: follows them:

def label(enabled: bool) -> str:
    match enabled:
        case True:
            "on"
        case False:
            "off"

def main() -> Result[(), IoError]:
    print(label(True))?
    print(label(3 > 4))?
    Ok(())
on
off

An integer literal takes the type of the value it matches and must fit it: case 300: is an error for a u8. A float is not a pattern; compare floats with if. A bare name still binds only at a payload position, so the catch-all for the whole value is case _:, or case _ as name: to bind it.

Each literal case costs one comparison, tried from the top, exactly like an if/elif chain. Put the common cases first in a long match.