Activity 12: Write the Match
How this works
The problems are on this paper, but you'll work through the problems in Rust Playground, and the finished functions go to Gradescope.
- Open play.rust-lang.org
- For each problem, copy the type (struct/enum) and the function signature into the playground
- Write the
matchthat makes the function produce the results in the table - Write a
fn mainthat calls it with the examples, and check you get what the table says - Paste your finished functions into the Gradescope assignment
Work with the people around you. But you'll submit individually.
A worked example
The problem gives you this:
enum Coin { Penny, Nickel, Dime }
fn value(c: Coin) -> u32 {
// your code here
}
| Call | Returns |
|---|---|
value(Coin::Penny) | 1 |
value(Coin::Dime) | 10 |
You write the body, and a main to check it:
enum Coin { Penny, Nickel, Dime } fn value(c: Coin) -> u32 { match c { Coin::Penny => 1, Coin::Nickel => 5, Coin::Dime => 10, } } fn main() { println!("{}", value(Coin::Penny)); println!("{}", value(Coin::Dime)); }
When you run it, if it prints 1 and 10, the problem is done.
Problem 1: Which way are we going
enum Direction { North, East, South, West }
fn label(dir: Direction) -> String {
// your code here
}
| Call | Returns |
|---|---|
label(Direction::North) | "going north" |
label(Direction::East) | "going east" |
label(Direction::South) | "going south" |
label(Direction::West) | "going west" |
Problem 2: A score that might not exist
fn describe(score: Option<u32>) -> String {
// your code here
}
Tip: to return an owned string you can use format! instead of println! to create a string with variable values. And to make a String out of a "string literal" like "hello" you need to use "hello".to_string().
| Call | Returns |
|---|---|
describe(Some(95)) | "scored 95" |
describe(Some(0)) | "scored 0" |
describe(None) | "did not take it" |
Problem 3: Class standing
Match on a struct, ignoring the fields you don't need.
struct Student {
name: String,
year: u32,
credits: u32,
}
fn standing(s: &Student) -> String {
// your code here
}
| Call | Returns |
|---|---|
standing(&Student { name: String::from("Kesar"), year: 3, credits: 96 }) | "senior" |
| a student with 72 credits | "junior" |
| a student with 30 credits | "sophomore" |
| a student with 12 credits | "first year" |
Senior is 90 credits or more, junior 60, sophomore 30.
Problem 4: Adding up to n
You'll use recursion here. You'll write a match with a base case and a recursive call.
fn sum_to(n: u32) -> u32 {
// your code here
}
sum_to(4) is 4 + 3 + 2 + 1 + 0.
| Call | Returns |
|---|---|
sum_to(0) | 0 |
sum_to(4) | 10 |
sum_to(10) | 55 |
Problem 5: The first even number
This one is more challenging. This needs a loop as well as a match, and it returns an Option.
fn first_even(nums: [u32; 5]) -> Option<u32> {
// your code here
}
| Call | Returns |
|---|---|
first_even([1, 3, 6, 7, 8]) | Some(6) |
first_even([2, 4, 6, 8, 10]) | Some(2) |
first_even([1, 3, 5, 7, 9]) | None |
Solutions
Problem 1: Direction
fn label(dir: Direction) -> String {
match dir {
Direction::North => String::from("going north"),
Direction::East => String::from("going east"),
Direction::South => String::from("going south"),
Direction::West => String::from("going west"),
}
}
Four arms, one per variant, and no _ needed. The return type is String, so we need this or "going north".to_string() technically.
Problem 2: a score that might not exist
fn describe(score: Option<u32>) -> String {
match score {
Some(n) => format!("scored {}", n),
None => "did not take it".to_string(),
}
}
Some(n) names the number so you can use it on the right. Two arms covers the whole type: an Option has nothing else in it.
Problem 3: class standing
fn standing(s: &Student) -> String {
match s {
&Student { credits, .. } if credits >= 90 => String::from("senior"),
&Student { credits, .. } if credits >= 60 => String::from("junior"),
&Student { credits, .. } if credits >= 30 => String::from("sophomore"),
_ => String::from("first year"),
}
}
Biggest number first. Put >= 30 at the top and every senior is a sophomore.
.. ignores name and year. The & is there because s is a &Student.
Problem 4: adding up to n
fn sum_to(n: u32) -> u32 {
match n {
0 => 0,
_ => n + sum_to(n - 1),
}
}
The base case is the arm that does not call itself. Without it, n - 1 runs past zero and a u32 cannot go negative.
Problem 5: the first even number
fn first_even(nums: [u32; 5]) -> Option<u32> {
for n in nums {
match n % 2 {
0 => return Some(n),
_ => {}
}
}
None
}
return leaves the whole function the moment you find one. None sits after the loop, for when it finishes without finding anything.