mirror of
https://github.com/alrayyes/wiki.git
synced 2024-11-23 03:56:23 +00:00
263 lines
4.1 KiB
Markdown
263 lines
4.1 KiB
Markdown
|
---
|
|||
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
```
|