Prep: Enums and match — 05r¶
Session: Friday Sep 11, 1h30 · Exercises: 05r_enums_match · Prep time: ~25 min · Lecture: Week 3 · Structs, impl, Enums, and match
What you will build¶
A process's state diagram, turned into code. You are given a ProcState enum whose variants carry data (a sleeper remembers its channel), an Event enum, and a table of legal transitions. You write the match that walks a process along the arrows, answers None for any pair not in the table, and lets a wakeup reach only a sleeper on that exact channel. The tests drive one full lifecycle from Unused back to Unused, confirm a wrong-channel wakeup leaves a sleeper asleep, and confirm an impossible event changes nothing.
Concepts you need¶
- Enums are sum types — exactly one of a fixed set — Week 3 · An enum is one of a fixed set · Rust for Systems: Enums are tagged unions
- Variants that carry data — building them, binding fields back out — Week 3 · An enum is one of a fixed set,
match, and the arms you cannot forget · Rust for Systems: Variants can carry data Option<T>— absence with its own type — Week 3 ·Option: an answer that may be missing, A sentinel, orOption· Rust for Systems:Option<T>- Exhaustive
match— arms,|,{ .. },E0004, the_trap — Week 3 ·match, and the arms you cannot forget, What_costs · Rust for Systems:matchis exhaustive - Guards, tuple patterns, fall-through — an
ifon an arm — Week 3 · Guards, and matching two values if let— a one-armmatch— Week 3 ·Option: an answer that may be missing · Rust for Systems:matchis exhaustive
Read before class¶
| What | Time |
|---|---|
Week 3 · Friday · 05r Enums and match, all four sections |
7 min |
| Week 3 · Problem 5: Trace guards and fall-through | 5 min |
Week 3 · For the exam: A sentinel, or Option and What _ costs. Not needed today; on Midterm 1 |
2 min |
Rust for Systems: Enums, Option, exhaustive match |
6 min |
Mental model¶
A console driver deciding whether a byte from the UART is worth keeping:
enum Rx { Byte(u8), Overrun, Idle }
fn accept(rx: Rx, room: usize) -> Option<u8> {
match (rx, room) {
(Rx::Byte(b), n) if n > 0 && b != 0 => Some(b), // guard: room, and not a NUL
(Rx::Byte(_), _) | (Rx::Idle, _) => None, // a failed guard lands here
(Rx::Overrun, _) => None, // its own arm: no `_`
}
}
if let Some(b) = accept(uart.read(), ring.free()) { ring.push(b); }
The tuple pattern tests two values at once. A guard is not an if inside the body: when it fails, the match keeps looking, so the "no" case is written once, below. Returning Option<u8> rather than u8 with zero meaning "nothing" forces the caller to take it apart. A kernel is mostly this shape: fixed states, fixed events, a table of legal pairs. Add Rx::Break and the compiler lists every match that has not decided, unless someone hid the variants behind _.
Check yourself¶
- A
matchoverProcStatecoversUnused,Runnable,Running, andSleeping { .. }, and nothing else. What does the compiler say, and what is the fix?Answer
error[E0004]: non-exhaustive patterns: ProcState::Zombie { .. } not covered. Add aZombie { .. }arm. Do not reach for_; it silences the check for every variant ever added. - In the mental model,
Rx::Byte(0)arrives withroom == 5. Which arm answers, and why not the first?Answer
The first arm's pattern matches, but its guardb != 0is false, so matching continues;(Rx::Byte(_), _)matches and the result isNone. A failed guard falls through; it never leaves thematch. - Why should a function answering "what state comes next" return
Option<ProcState>rather thanProcStatewith an extraInvalidvariant?Answer
Option<ProcState>is a different type: the caller must unwrap it withmatchorif let, so "no legal transition" cannot be mistaken for a real state and stored into a process table slot. AnInvalidvariant is just another value the compiler cannot flag.
What "done" looks like¶
oslings run is green, then oslings submit before you leave. Not green? Submit anyway — the tests that pass earn their share — then finish it at a make-up session (office hours, on the class network) for three quarters, or anywhere else for half, and submit again.
If you finish early¶
Rustlings 08_enums and 12_options drill today's patterns. In 100 Exercises To Learn Rust, chapter 5 covers enums, match, variants with data, if let, and Option. Or start next Thursday's prep page, Collections and traits.