The Option type means that the value might by of type Some (there is something) or None:
pubenumOption<T> {None,Some(T),}
You can use functions such as is_some()oris_none() to check the value of the Option.
Macros
Macros are more powerful than functions because they expand to produce more code than the code you’ve written manually. For example, a function signature must declare the number and type of parameters the function has. Macros, on the other hand, can take a variable number of parameters: we can call println!("hello") with one argument or println!("hello {}", name) with two arguments. Also, macros are expanded before the compiler interprets the meaning of the code, so a macro can, for example, implement a trait on a given type. A function can’t, because it gets called at runtime and a trait needs to be implemented at compile time.
macro_rules!my_macro { () => {println!("Check out my macro!"); }; ($val:expr) => {println!("Look at this other macro: {}", $val); }}fnmain() {my_macro!();my_macro!(7777);}// Export a macro from a modulemod macros { #[macro_export]macro_rules!my_macro { () => {println!("Check out my macro!"); }; }}
Iterate
// Iterate through a vectorlet my_fav_fruits =vec!["banana", "raspberry"];letmut my_iterable_fav_fruits = my_fav_fruits.iter();assert_eq!(my_iterable_fav_fruits.next(), Some(&"banana"));assert_eq!(my_iterable_fav_fruits.next(), Some(&"raspberry"));assert_eq!(my_iterable_fav_fruits.next(), None); // When it's over, it's none// One line iteration with actionmy_fav_fruits.iter().map(|x|capitalize_first(x)).collect()// Hashmap iterationfor (key, hashvalue) in&*map {for key in map.keys() {for value in map.values() {
Recursive Box
enumList {Cons(i32, List),Nil,}let list =Cons(1, Cons(2, Cons(3, Nil)));
Conditionals
if
let n =5;if n <0 {print!("{} is negative", n);} elseif n >0 {print!("{} is positive", n);} else {print!("{} is zero", n);}
match
match number {// Match a single value1=>println!("One!"),// Match several values2|3|5|7|11=>println!("This is a prime"),// TODO ^ Try adding 13 to the list of prime values// Match an inclusive range13..=19=>println!("A teen"),// Handle the rest of cases _ =>println!("Ain't special"),}let boolean =true;// Match is an expression toolet binary =match boolean {// The arms of a match must cover all the possible valuesfalse=>0,true=>1,// TODO ^ Try commenting out one of these arms};
letmut n =1;while n <101 {if n %15==0 {println!("fizzbuzz"); } elseif n %5==0 {println!("buzz"); } else {println!("{}", n); } n +=1;}
for
for n in1..101 {if n %15==0 {println!("fizzbuzz"); } else {println!("{}", n); }}// Use "..=" to make inclusive both endsfor n in1..=100 {if n %15==0 {println!("fizzbuzz"); } elseif n %3==0 {println!("fizz"); } elseif n %5==0 {println!("buzz"); } else {println!("{}", n); }}// ITERATIONSlet names =vec!["Bob", "Frank", "Ferris"];//iter - Doesn't consume the collectionfor name in names.iter() {match name {&"Ferris"=>println!("There is a rustacean among us!"), _ =>println!("Hello {}", name), }}//into_iter - COnsumes the collectionfor name in names.into_iter() {match name {"Ferris"=>println!("There is a rustacean among us!"), _ =>println!("Hello {}", name), }}//iter_mut - This mutably borrows each element of the collectionfor name in names.iter_mut() {*name =match name {&mut"Ferris"=>"There is a rustacean among us!", _ =>"Hello", }}
if let
let optional_word =Some(String::from("rustlings"));iflet word = optional_word {println!("The word is: {}", word);} else {println!("The optional word doesn't contain anything");}
while let
letmut optional =Some(0);// This reads: "while `let` destructures `optional` into// `Some(i)`, evaluate the block (`{}`). Else `break`.whileletSome(i) = optional {if i >9 {println!("Greater than 9, quit!"); optional =None; } else {println!("`i` is `{:?}`. Try again.", i); optional =Some(i +1); }// ^ Less rightward drift and doesn't require// explicitly handling the failing case.}
Traits
Create a new method for a type
traitAppendBar {fnappend_bar(self) -> Self;}implAppendBarforString {fnappend_bar(self) -> Self{format!("{}Bar", self) }}let s =String::from("Foo");let s = s.append_bar();println!("s: {}", s);
An Arc can use Clone to create more references over the object to pass them to the threads. When the last reference pointer to a value is out of scope, the variable is dropped.
use std::sync::Arc;let apple =Arc::new("the same apple");for _ in0..10 {let apple =Arc::clone(&apple); thread::spawn(move|| {println!("{:?}", apple); });}
Threads
In this case we will pass the thread a variable it will be able to modify