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 = 0 u8 ;
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 ( 0 u8 );
match some_u8_value {
Some ( 3 ) => println! ( "three" ),
_ => (),
}
}
is the same as
fn main () {
let some_u8_value = Some ( 0 u8 );
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 ;
}
}