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

Structs, kinds and matching

Kinds

A kind is a type whose value is one of several variants. Each variant can carry its own fields.

kind Shape
    Circle(r: f64)
    Rect(w: f64, h: f64)
    Empty

fn area(s: &Shape) -> f64
    match s
        Circle(r: r) -> 3.0 * r * r
        Rect(w: w, h: h) -> w * h
        Empty -> 0.0

struct Point
    x: i64
    y: i64

impl Point
    fn origin() -> Point = Point(x: 0, y: 0)
    fn moved(self, dx: i64) -> Point = Point(x: self.x + dx, y: self.y)

fn first_even(xs: &[i64]) -> i64?
    for x in xs
        if x % 2 == 0
            return some(x)
    return none

fn or_zero(v: i64?) -> i64
    match v
        some(x) -> x
        none -> 0

const NUMS: List[i64] = [3, 5, 8, 9]
const BOX: Shape = Rect(w: 2.0, h: 3.0)
const NOTHING: Shape = Empty

check area(&BOX) == 6.0
check area(&NOTHING) == 0.0
check Point.origin().moved(4).x == 4
check or_zero(first_even(&NUMS)) == 8

match looks at a value and runs the arm whose pattern fits. Circle(r: r) matches a circle and names its radius r.

The checker requires a match to cover every variant. Forgetting one is refused, so adding a variant later shows you every place that must handle it:

kind Light
    Red
    Green
    Yellow

fn next(l: Light) -> Light
    match l
        Red -> return Green
        Green -> return Yellow
$ rce check missing_case.rce
REFUSED missing_case.rce: line 7: W-MATCH-1 match is not exhaustive: missing Yellow
exit status: 1

A _ pattern matches anything and can serve as the last arm.

Structs and impl

A struct groups named fields. Point(x: 0, y: 0) builds one; fields are always passed by name. impl Point adds functions that belong to the type. Point.origin() calls one that takes no self; p.moved(4) calls one that does.

Options

i64? is an option: either some(value) or none. RCE has no null, so an empty result is always visible in the type. first_even returns none when it finds no even number, and or_zero uses match to handle both cases.

Borrowed arguments

area(s: &Shape) takes a borrow of a shape: it can read the shape but does not take it over. You pass a borrow with &, as in area(&BOX). Borrows are what chapter 9 is about. One rule shows up already: you can only borrow a place, such as a variable or a constant, not a value that was just built. That is why the checks use the named constants BOX and NOTHING.

What you learned

  • kind with variants, struct with fields, impl for functions on a type.
  • match must cover every case (rule W-MATCH-1).
  • T? options with some and none instead of null.