
ENUMS AND PATTERN MATCHING, Ch6
this chapter covers...
-
how an enum can encode meaning along with data
-
explore particulary useful enum, called Option
-
how pattern matching in the match expression
-
if let construct
Rust's enums are most similar to algebraic data types in functional languages, such as F#, OCaml, and Haskell.
defining and using enum
fn main() { enum IpAddrKind { V4, // or V4(u8, u8, u8, u8) V6, // or V6(String), } let four = IpAddrKind::V4; // or IpAddrKind::V4(127, 0, 0, 1); let six = IpAddrKind::V6; // or IpAddrKind::V6(String::from("::1")); }
-
example of enum
enum Msg { Quit, Move { x: i32, y: i32}, Write(String), ChangeColor(i32, i32, i32), }
-> Msg Enum whose variants each store different amounts and types of values.
- Quit has no data associated with it at all.
- Move includes an anonymous struct inside it.
- Write includes a single String.
- ChangeColor includes a three i32 values
-
why are we using enum? -> if we use different structs, which each have their own type, we couldn't as easily define a fucntion.
The Option Enum and Its Advantages over Null Values.
-
Expressing this concept in terms of the type system means the compiler can check whether you've handled all the cases you should be handling.
-
Rust does not have null feature. -> the problem with null values is that if you try to use null value as not-null value, you'll get an error of some kind.
-> the concept that null is trying to express is still a useful one: a null is value that is currently invalid or absent for some reason.
-
Rust does have an enum that can encode the concept of a value being present of absent.
enum Option<T> {
Some(T),
None,
}
let some_number = Some(5);
let some_string = Some("a string");
let absent_number : Option<i32> = None;
- it included in the prelude.
- you can you Some or None directly.
- if we use None rather than Some, we need to tell Rust what type of Option
we have because compiler can not infer the type. - can not use value inside some directly, we need to take the value from Some
The match Control Flow Operator
let some_val = Some(123);
match some_val {
Some(t) -> println!("in some, there is value : {}", t),
_ -> println!("there is no value at all"), // or we can use use (),
};
- in this case, uses '_' in match this means it can take all cases that aren't specified before it.
- () is just the unit type, nothing will happen in the _ case.
if let
#![allow(unused)] fn main() { let some_val = Some(123); if let val = some_val { println!("there is vale inside some_val : {}", val); }else{ println!("none"); } }
Sommary
- how to create custom enum type.
- Option
- match & if let