compiler cannot guarantee a matching pattern for one or more possible inputs to a match expression. Guaranteed matches are required in order to assign values to match expressions, or alternatively, determine the flow of execution. Erroneous code example: ``` enum Terminator { HastaLaVistaBaby, TalkToMyHand, } let x = Terminator::HastaLaVistaBaby; match x { // error: non-exhaustive patterns: `HastaLaVistaBaby` not covered Terminator::TalkToMyHand => {} } ``` If you encounter this error you must alter your patterns so that every possible value of the input type is matched. For types with a small number of variants (like enums) you should probably cover all cases explicitly. Alternatively, the
None; println!("{}", value.unwrap()); } thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', ../src/libcore/option.rs:326 note: Run with `RUST_BACKTRACE=1` for a backtrace. You know exactly where panic can occur
=> println!("{}", x), None => println!("Nothing"), } value.unwrap_or(5) Pattern matching Use a default value Some(String::from("Barcamp")).map(|s| s.len()); Apply a function
add a trait implementation to everything ◦ Enum ◦ Struct ◦ Primitive types ◦ Other module's enum and struct • Trait must be imported before you can use it
<anon>:4:20 | 3 | let y = x; | - value moved here 4 | println!("{}", x.len()); | ^ value used here after move <std macros>:2:27: 2:58 note: in this expansion of format_args! <std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>) <anon>:4:5: 4:29 note: in this expansion of println! (defined in <std macros>) | = note: move occurs because `x` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait error: aborting due to previous error
one owner 2. Others can borrow it from the owner but the reference must last no longer than the owner let y; if true { let x = vec![1]; y = &x; } println!("{}", y.len());
--> <anon>:5:14 5 | y = &x; | ^ note: reference must be valid for the block suffix following statement 0 at 2:10... --> <anon>:2:11 2 | let y; | ^ note: ...but borrowed value is only valid for the block suffix following statement 0 at 4:24 --> <anon>:4:25 4 | let x = vec![1]; | ^
one owner 2. Others can borrow it from the owner but the borrow must last no longer than the owner 3. Only one mutable reference let mut x = vec![1]; x.push(5); let y = &x; y.push(6);
one owner 2. Others can borrow it from the owner but the borrow must last no longer than the owner 3. Only one mutable reference let mut x = vec![1]; x.push(5); let y = &mut x; x.push(6);
than once at a time --> <anon>:5:5 | 4 | let y = &mut x; | - first mutable borrow occurs here 5 | x.push(6); | ^ second mutable borrow occurs here 6 | } | - first borrow ends here
but it borrows `x`, which is owned by the current function --> <anon>:5:31 | 5 | let child = thread::spawn(|| *x += 1); | ^^ - `x` is borrowed here | | | may outlive borrowed value `x` | help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword, as shown: | let child = thread::spawn(move || *x += 1);
<anon>:6:5 | 5 | let child = thread::spawn(move || *x += 1); | ------- value moved (into closure) here 6 | *x += 1; | ^^^^^^^ value used here after move | = note: move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
time • Generic can be dispatched statically (like C++ templates) ◦ Rust has zero-cost abstraction as its core value: pay for only what you use • Rust have no garbage collection • Rust allocate all local variable on the stack