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