2024-05-06 20:40:05 +00:00
|
|
|
|
---
|
2024-10-30 17:04:36 +00:00
|
|
|
|
date: 20200902
|
2024-05-06 20:40:05 +00:00
|
|
|
|
id: b95f09af-2cd0-46f2-872e-3cb542d2b2e9
|
|
|
|
|
title: Rust enums
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
# Basics
|
|
|
|
|
|
|
|
|
|
Rust also supports
|
|
|
|
|
[enums](https://doc.rust-lang.org/rust-by-example/custom_types/enum.html).
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
use std::fmt::Debug;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
enum Message {
|
|
|
|
|
Write(String),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let m = Message::Write(String::from("Hello!"));
|
|
|
|
|
println!("{:?}", m)
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
# Methods
|
|
|
|
|
|
|
|
|
|
As with [structs](20200831193417-structs), methods can be defined as
|
|
|
|
|
well:
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
use std::fmt::Debug;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
enum Message {
|
|
|
|
|
Write(String),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Message {
|
|
|
|
|
fn call(&self) {
|
|
|
|
|
println!("tralala");
|
|
|
|
|
println!("{:?}", self)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let m = Message::Write(String::from("Hello!"));
|
|
|
|
|
m.call();
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
# Standard library enums
|
|
|
|
|
|
|
|
|
|
## Option
|
|
|
|
|
|
|
|
|
|
Instead of \`null\` Rust has the
|
|
|
|
|
[Option](https://doc.rust-lang.org/std/option/enum.Option.html) enum
|
|
|
|
|
built in:
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
fn main() {
|
|
|
|
|
let some_number = Some(5);
|
|
|
|
|
let some_string = Some("a string");
|
|
|
|
|
|
|
|
|
|
let absent_number: Option<i32> = None;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The cool thing about using Option is that \`Option\<T\>\` and \`T\` are
|
|
|
|
|
different types, therefore the programmer has to define if NULL is
|
|
|
|
|
acceptable beforehand. The following won't run:
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
fn main() {
|
|
|
|
|
let x: i8 = 5;
|
|
|
|
|
let y: Option<i8> = Some(5);
|
|
|
|
|
|
|
|
|
|
let sum = x + y;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Huzzah, No more having to worry about incorrectly assuming a not null
|
|
|
|
|
value!
|
|
|
|
|
|
|
|
|
|
# Match control flow operator
|
|
|
|
|
|
|
|
|
|
Think of \`switch\`, but for enums.
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
enum Coin {
|
|
|
|
|
Penny,
|
|
|
|
|
Nickel,
|
|
|
|
|
Dime,
|
|
|
|
|
Quarter,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn value_in_cents(coin: Coin) -> u8 {
|
|
|
|
|
match coin {
|
|
|
|
|
Coin::Penny => {
|
|
|
|
|
println!("Lucky penny!");
|
|
|
|
|
1
|
|
|
|
|
}
|
|
|
|
|
Coin::Nickel => 5,
|
|
|
|
|
Coin::Dime => 10,
|
|
|
|
|
Coin::Quarter => 25,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() {}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Patterns that bind to values
|
|
|
|
|
|
|
|
|
|
Another useful feature of match arms is that they can bind to the parts
|
|
|
|
|
of the values that match the pattern. This is how we can extract values
|
|
|
|
|
out of enum variants.
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
enum UsState {
|
|
|
|
|
Alabama,
|
|
|
|
|
Alaska,
|
|
|
|
|
// --snip--
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum Coin {
|
|
|
|
|
Penny,
|
|
|
|
|
Nickel,
|
|
|
|
|
Dime,
|
|
|
|
|
Quarter(UsState),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn value_in_cents(coin: Coin) -> u8 {
|
|
|
|
|
match coin {
|
|
|
|
|
Coin::Penny => 1,
|
|
|
|
|
Coin::Nickel => 5,
|
|
|
|
|
Coin::Dime => 10,
|
|
|
|
|
Coin::Quarter(state) => {
|
|
|
|
|
println!("State quarter from {:?}!", state);
|
|
|
|
|
25
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
value_in_cents(Coin::Quarter(UsState::Alaska));
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Matching with Option\<T\>
|
|
|
|
|
|
|
|
|
|
\`match\` also plays nice with \`Option\<t\>\`:
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
fn main() {
|
|
|
|
|
fn plus_one(x: Option<i32>) -> Option<i32> {
|
|
|
|
|
match x {
|
|
|
|
|
None => None,
|
|
|
|
|
Some(i) => Some(i + 1),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let five = Some(5);
|
|
|
|
|
let six = plus_one(five);
|
|
|
|
|
let none = plus_one(None);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## The \_ Placeholder
|
|
|
|
|
|
|
|
|
|
Rust also has a pattern we can use when we don’t want to list all
|
|
|
|
|
possible values:
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
fn main() {
|
|
|
|
|
let some_u8_value = 0u8;
|
|
|
|
|
match some_u8_value {
|
|
|
|
|
1 => println!("one"),
|
|
|
|
|
3 => println!("three"),
|
|
|
|
|
5 => println!("five"),
|
|
|
|
|
7 => println!("seven"),
|
|
|
|
|
_ => (),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## if let syntax suger
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
fn main() {
|
|
|
|
|
let some_u8_value = Some(0u8);
|
|
|
|
|
match some_u8_value {
|
|
|
|
|
Some(3) => println!("three"),
|
|
|
|
|
_ => (),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
is the same as
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
fn main() {
|
|
|
|
|
let some_u8_value = Some(0u8);
|
|
|
|
|
if let Some(3) = some_u8_value {
|
|
|
|
|
println!("three");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
and
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
enum UsState {
|
|
|
|
|
Alabama,
|
|
|
|
|
Alaska,
|
|
|
|
|
// --snip--
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum Coin {
|
|
|
|
|
Penny,
|
|
|
|
|
Nickel,
|
|
|
|
|
Dime,
|
|
|
|
|
Quarter(UsState),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let coin = Coin::Penny;
|
|
|
|
|
let mut count = 0;
|
|
|
|
|
match coin {
|
|
|
|
|
Coin::Quarter(state) => println!("State quarter from {:?}!", state),
|
|
|
|
|
_ => count += 1,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
is the same as
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
enum UsState {
|
|
|
|
|
Alabama,
|
|
|
|
|
Alaska,
|
|
|
|
|
// --snip--
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum Coin {
|
|
|
|
|
Penny,
|
|
|
|
|
Nickel,
|
|
|
|
|
Dime,
|
|
|
|
|
Quarter(UsState),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let coin = Coin::Penny;
|
|
|
|
|
let mut count = 0;
|
|
|
|
|
if let Coin::Quarter(state) = coin {
|
|
|
|
|
println!("State quarter from {:?}!", state);
|
|
|
|
|
} else {
|
|
|
|
|
count += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|