mirror of
https://github.com/alrayyes/wiki.git
synced 2024-11-22 03:26:22 +00:00
4.1 KiB
4.1 KiB
date | id | title |
---|---|---|
2020-09-02 | b95f09af-2cd0-46f2-872e-3cb542d2b2e9 | Rust enums |
Basics
Rust also supports enums.
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, methods can be defined as well:
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 enum built in:
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:
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.
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.
#[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>`:
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:
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
fn main() {
let some_u8_value = Some(0u8);
match some_u8_value {
Some(3) => println!("three"),
_ => (),
}
}
is the same as
fn main() {
let some_u8_value = Some(0u8);
if let Some(3) = some_u8_value {
println!("three");
}
}
and
#[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
#[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;
}
}