Rust conditionals: Difference between revisions
(→Basics) |
|||
(9 intermediate revisions by the same user not shown) | |||
Line 13: | Line 13: | ||
</blockquote><!-- if statement --> | </blockquote><!-- if statement --> | ||
= | = assign if = | ||
<blockquote> | <blockquote> | ||
<syntaxhighlight lang="rust"> | <syntaxhighlight lang="rust"> | ||
let weather = if season == "fall" { "lovely" } else { "fine I guess" } // ternary | let weather = if season == "fall" { "lovely" } else { "fine I guess" } // ternary operator | ||
</syntaxhighlight> | </syntaxhighlight> | ||
</blockquote><!-- Ternary operator --> | </blockquote><!-- Ternary operator --> | ||
= | = match = | ||
<blockquote> | |||
== Basics == | |||
<blockquote> | <blockquote> | ||
Like a switch statement,<br> | Like a switch statement,<br> | ||
where compiler ensures that all possible options in datatype's range are handled,<br> | |||
that ensures the output type is the same for all branches (<code>panic!()/break/return</code> also allowed). | |||
Especially useful for enums. | |||
In the following case, if <code>_</code> was omitted<br> | In the following case, if <code>_</code> was omitted<br> | ||
Line 45: | Line 49: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
</blockquote><!-- Basics --> | |||
== Matching Enums == | |||
<blockquote> | |||
When matching a parametrized enum, you can access the tuple/struct/value that is bound to it | When matching a parametrized enum, you can access the tuple/struct/value that is bound to it | ||
<syntaxhighlight lang="rust"> | <syntaxhighlight lang="rust"> | ||
Line 56: | Line 63: | ||
let pet = Pet::Lizard(5); | let pet = Pet::Lizard(5); | ||
match pet { | match pet { | ||
Cat(name, age) => { format!("cat, name={}, age={}", name, age) }, | Pet::Cat(name, age) => { format!("cat, name={}, age={}", name, age) }, | ||
Dog(dog) => { format!("dog, name={dog.name}, age={dog.age}") }, | Pet::Dog(dog) => { format!("dog, name={dog.name}, age={dog.age}") }, | ||
Lizard(age) => { format!("lizard, age={}", age) } | Pet::Lizard(age) => { format!("lizard, age={}", age) } | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
</blockquote><!-- Matching Enums --> | |||
== Matching Option == | |||
<blockquote> | |||
Option is just an enum, generally if you don't have a specific behaviour for <code>None</code>,<br> | |||
you return a new <code>None</code> in that branch.<br> | |||
However this an opportunity to fail if it is an appropriate location for it. | |||
<syntaxhighlight lang="rust"> | |||
match some_value { | |||
Some(x) => "you received a value!", | |||
None => None, | |||
} | |||
</syntaxhighlight> | |||
</blockquote><!-- Matching Option --> | |||
== Matching Ranges == | |||
<blockquote> | |||
<syntaxhighlight lang="rust"> | |||
match val { | |||
i32::MIN..0 => "less than zero", | |||
0..5 => "is zero to five", | |||
5..i32::MAX => "is over five", | |||
} | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="rust"> | |||
use std::cmp::Ordering; | |||
// todo | |||
</syntaxhighlight> | |||
</blockquote><!-- Matching Ranges --> | |||
</blockquote><!-- Pattern Matching --> | </blockquote><!-- Pattern Matching --> | ||
= if let = | |||
<blockquote> | |||
if let is essentially a one-branch <code>match</code>,<br> | |||
only caring about the value if it is non-none.<br> | |||
if <code>my_value</code> is <code>None</code>, then it returns <code>None</code> and the block does not run. | |||
it does not take advantage of exhaustiveness checks. | |||
<syntaxhighlight lang="rust"> | |||
if let Some(x) = my_value { | |||
println!("The value {} was bound!!", x); | |||
} | |||
</syntaxhighlight> | |||
</blockquote><!-- if let --> |
Latest revision as of 23:54, 9 February 2023
if statement
if num < 5 { // .. } else if { // .. } else { // .. }
assign if
let weather = if season == "fall" { "lovely" } else { "fine I guess" } // ternary operator
match
Basics
Like a switch statement,
where compiler ensures that all possible options in datatype's range are handled,
that ensures the output type is the same for all branches (panic!()/break/return
also allowed).Especially useful for enums.
In the following case, if
_
was omitted
you'd need to ensure the full range of possible i32 numbers were supported!.// if num is '1', returns 'a' // if num is >2, returns 'c' let result = match num { 1 => "a", 2 => "b", _ => "c", // anything other than 1 or 2 }You can match multiple values
let result = match num { 1 | 3 | 5 => "one three or five", _ => "something else" }Matching Enums
When matching a parametrized enum, you can access the tuple/struct/value that is bound to it
enum Pet { Cat(String, u8), Dog{name: String, age: u8}, Lizard(u8), } let pet = Pet::Lizard(5); match pet { Pet::Cat(name, age) => { format!("cat, name={}, age={}", name, age) }, Pet::Dog(dog) => { format!("dog, name={dog.name}, age={dog.age}") }, Pet::Lizard(age) => { format!("lizard, age={}", age) } }Matching Option
Option is just an enum, generally if you don't have a specific behaviour for
None
,
you return a newNone
in that branch.
However this an opportunity to fail if it is an appropriate location for it.match some_value { Some(x) => "you received a value!", None => None, }Matching Ranges
match val { i32::MIN..0 => "less than zero", 0..5 => "is zero to five", 5..i32::MAX => "is over five", }use std::cmp::Ordering; // todo
if let
if let is essentially a one-branch
match
,
only caring about the value if it is non-none.
ifmy_value
isNone
, then it returnsNone
and the block does not run.it does not take advantage of exhaustiveness checks.
if let Some(x) = my_value { println!("The value {} was bound!!", x); }