In this lecture, we're going to explore an alternative feature to conditional statements.
Rust has a syntax feature called Match Expressions.
They allow us to perform a comparison against a series of patterns if there's a match.
We can run some code.
Theoretically, we can control the flow of an application with match expressions.
After reviewing the syntax for match expressions, we'll discuss the differences between match expressions
and conditional statements.
Let's get started.
At the moment, we're informing the user of their qualification for free shipping.
However, we haven't updated the total.
If the user has free shipping, their total will remain the same.
On the other hand, if they don't qualify, the shipping price will need to be added on top of the total.
Theoretically, we could update the total inside the IFF block for demonstration purposes.
Let's learn how to perform this action with match expressions.
First things first.
The total variable will need to be immutable, as we learned previously.
Variables are immutable.
Updating the total will require the mute keyword on the total variable.
Next, let's create a variable to store a Boolean value below the total value defined immutable variable
called free shipping with an initial value of false.
We're going to assume the user does not qualify for a free shipping.
This variable should be updated inside the IFF block will toggle the value to true.
The next step is to check this variable to calculate the final cost after the series of conditional
statements.
Let's add the match keyword.
The match keyword performs a similar operation to a conditional statements.
We can use match expressions to compare values after typing the match keyword.
We need to provide a value to perform comparisons on.
We'll add the free shipping variable.
Next, we need to add curly braces.
Inside the curly braces, we need to provide a list of values to compare against the variable.
Unlike conditional statements, match expressions are exhaustive.
This means we need to account for every possibility.
In our example, our variable is a Boolean.
Hooligans can have one of two values.
They can be true or false.
We are required to account for both scenarios.
For example, inside the block, let's handle the scenario where the free shipping variable is true.
Then, after the value, we can add a fat error.
The code after this arrow is the code to execute if there's a match, we'll update the total property
by adding zero, which essentially means they won't have to pay for free shipping.
After adding this value, we're thrown in error, the error states we haven't covered a false value.
Rust is very strict and demanding with match expressions.
We can't permit a possibility.
All possibilities must be handled.
Despite the strictness of this feature, it's prevalent among rust developers.
This behavior can be good for developers.
It forces us to handle all scenarios if we forget a possible value.
The compiler will warn us ahead of time.
You may want this behavior when working on large applications as your application grows.
It's possible to overlook a pattern in your control flow.
Russ can warn us when this problem happens.
Let's handle a false pattern.
If the free shipping variable is false or going to update the total variable by five.
The free shipping variable is false, thus we should charge the buyer for shipping.
They haven't met our threshold at the end of the function.
Let's print the total variable.
Keep in mind, the print line macro will not output numbers unless we format the string.
Let's compile our project.
It looks like I'm out of luck.
My total is below the threshold for a free shipping.
I'll have to pay for shipping on my purchase.
As you can see, our app works.
We were able to update the total variable with a match expression.
As I stated before, it's possible to exclusively stick with conditional statements.
However, matches are more useful for their strictness.
We can take our expression a step further.
The match keyword creates an expression.
As a reminder, expressions are pieces of code that evaluate a value.
For example, arithmetic operations are expressions such as the return value in the add function.
The match keyword can return a value.
Theoretically, we can refactor our current solution to update the total variable.
Let me show you what I mean.
Instead of updating the total variable in the patterns, we can move the assignment outside the match
expression.
This code will result in the same behavior, the values returned by our patterns will be returned by
the expression.
Thus, the total variable will be updated.
We can run our compiler to view the results.
As you can see, everything works like before you're more than free to use the previous solution, in
my opinion.
I think this solution is more readable.
It's clear that we're trying to update the total variable based on a condition.
Match expressions seem great.
So what's the catch?
If we have unlimited patterns, we need to handle them all.
The current expression will have two possible values either the free shipping variable is true or false.
It can't be any other value.
What if we run a match against a number?
Let's find out below the first match expression.
Let's perform a match against the total variable.
Inside the expression, we'll check if the variables match the numbers one or two in both patterns will
output a message.
There is an infinite amount of numbers the compiler is complaining we haven't accounted for all patterns.
But how can we?
We don't have time to enter every number imaginable.
Luckily, the match operator has us covered.
We can insert a wildcard character to catch patterns we haven't added inside the block at an underscore
character, the underscore character as a fallback pattern.
If the match operator cannot find a match, the code from this pattern will run.
And this example, we will print a message that says the following no match found.
Let's compile our project.
As you can see, the match operator was not able to find a match and defaulted to the underscore pattern.
There's a lot more we can do with matches, but this information will suffice.
There are a couple more topics I want to cover before moving onto WebAssembly.
I'll see you in the next lecture.