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
kindwith variants,structwith fields,implfor functions on a type.matchmust cover every case (ruleW-MATCH-1).T?options withsomeandnoneinstead of null.