Bind the value a match selects
A match at the end of a function supplies the function’s result. To use the
selected value in the middle of a function, write the match as the value of a
binding. The final expression of the selected case becomes the value:
enum Shape:
Dot
Square(i64)
Rect(i64, i64)
def paint_cost(shape: Shape) -> Result[i64, OverflowError[i64]]:
area = match shape:
case Shape.Dot:
return Ok(1)
case Shape.Square(side):
side * side
case Shape.Rect(width, height):
width * height
Ok(area * 10)
def main() -> Result[(), IoError | OverflowError[i64]]:
print(paint_cost(Shape.Dot)?)?
print(paint_cost(Shape.Square(3))?)?
print(paint_cost(Shape.Rect(2, 5))?)?
Ok(())
1
90
100
The cases that continue must produce one type. A case may instead leave with
return, break, continue, or ?, as Shape.Dot does; it then supplies no
value and nothing is bound.
The same block is the value of an assignment to a mut local, a field, or a
collection element, and of return. An annotation gives every case its
expected type, which Nothing needs:
def half(number: i64) -> Option[i64]:
two: Positive[i64] = 2
return match number % two:
case 0:
Some(number // two)
case _:
Nothing
def main() -> Result[(), AllocError | IoError]:
mut halves = [0, 0]?
for index in range(2):
found: Option[i64] = match index:
case 0:
half(8)
case _:
Nothing
halves[index] = match found:
case Some(value):
value
case Nothing:
-1
print(halves)?
print(half(3))?
Ok(())
[4, -1]
Option[i64].Nothing
return match returns the final expression of the selected case, so nothing
after the block runs.
The block must be the whole right-hand side. Inside a larger expression it is rejected; bind it first:
def main() -> Result[(), IoError]:
number = 3
doubled = 2 * match number:
case 3:
30
case _:
0
print(doubled)?
Ok(())
a `match` block is a value only as the whole right side of a binding, a single-target assignment, or `return`; bind its value to a name first
Cases that disagree are rejected at the case that differs:
def main() -> Result[(), IoError]:
number = 3
label = match number:
case 3:
"three"
case _:
0
print(label)?
Ok(())
expected str, got i64
The reference lists the remaining rules, including why the value cannot be a reference.