├── .gitignore ├── 1.hello-world ├── README.md └── hello.rs ├── 2.variables ├── README.md └── var.rs ├── 3.expression └── readme.md ├── 3.function ├── README.md └── func.rs ├── 4.Closures ├── README.md └── closure.rs ├── 5.strings ├── README.md └── string.rs ├── 6.If-else ├── README.md └── ifelse.rs ├── 7.Match ├── README.md └── match.rs ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/rust 3 | # Edit at https://www.gitignore.io/?templates=rust 4 | 5 | ### Rust ### 6 | # Generated by Cargo 7 | # will have compiled files and executables 8 | /target/ 9 | 10 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 11 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 12 | Cargo.lock 13 | 14 | # These are backup files generated by rustfmt 15 | **/*.rs.bk 16 | 17 | # End of https://www.gitignore.io/api/rust 18 | * 19 | !/**/ 20 | !*.* 21 | .idea -------------------------------------------------------------------------------- /1.hello-world/README.md: -------------------------------------------------------------------------------- 1 | 1. Hello World 2 | 3 | ```rust 4 | fn main() { 5 | println!("Hi There!{}", "Ankur Anand"); 6 | } 7 | ``` 8 | 9 | compile the code 10 | `rustc hello.rs` 11 | 12 | Run the executables 13 | `./hello` on linux 14 | 15 | **Important `println!` is not an function. It's a macro in rust. (macro end with `!`)** 16 | 17 | ### println! macro 18 | will accept an string, with `{}` as placeholder. 19 | 20 | First string argument is **format strings** 21 | with **{}** as **format specifiers**. 22 | 23 | #### `{}` specifier for primitives types. 24 | #### `{:?}` specifier for other types. 25 | 26 | ## Advanced (Skip if first time) 27 | 28 | When an **format specifier** founds it's corresponding substitue value, it calls a `method` on that value, which return a string format of that value. (More on this later) -------------------------------------------------------------------------------- /1.hello-world/hello.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hi There!{}", "Ankur Anand"); 3 | } 4 | -------------------------------------------------------------------------------- /2.variables/README.md: -------------------------------------------------------------------------------- 1 | ## How to store a value and refer it later ? 2 | 3 | In rust we can decalare a variable with `let` keyword. 4 | 5 | ```rust 6 | fn main() { 7 | let x_immutable = 10; 8 | println!("x value : {}", x_immutable); 9 | } 10 | ``` 11 | 12 | ```go 13 | var v int 14 | v = 2 15 | v = 3 16 | ``` 17 | The above go code where you can reassign v as many times as you wish. 18 | 19 | **Rust default variable declaration doesn't allow you to do this** 20 | 21 | > All the variables are **immutable** by **default** in Rust. i.e Once the variable has been decalared and initialized, you cannot assign some other value to it by default. 22 | 23 | Trying to reassign will throw you an error at compile time. 24 | 25 | ```rust 26 | fn main() { 27 | let x_immutable = 10; 28 | println!("x value : {}", x_immutable); 29 | x_immutable = 20; 30 | } 31 | ``` 32 | 33 | ```sh 34 | error[E0384]: cannot assign twice to immutable variable `x_immutable` 35 | --> var.rs:4:5 36 | | 37 | 2 | let x_immutable = 10; 38 | | ----------- first assignment to `x_immutable` 39 | 3 | println!("x value : {}", x_immutable); 40 | 4 | x_immutable = 20; 41 | | ^^^^^^^^^^^^^^^^ cannot assign twice to immutable variable 42 | ``` 43 | 44 | So if We want to reassign variable to some other value, add `mut` keyword before it. 45 | 46 | ```rust 47 | fn main() { 48 | let mut y_mutable = 20; 49 | println!("y mut {}", y_mutable); 50 | y_mutable = 30; 51 | println!("y mut {}", y_mutable); 52 | } 53 | ``` -------------------------------------------------------------------------------- /2.variables/var.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let x_immutable = 10; 3 | println!("x value : {}", x_immutable); 4 | // x_immutable = 20; 5 | let mut y_mutable = 20; 6 | println!("y mut {}", y_mutable); 7 | y_mutable = 30; 8 | println!("y mut {}", y_mutable); 9 | } 10 | -------------------------------------------------------------------------------- /3.expression/readme.md: -------------------------------------------------------------------------------- 1 | ## Expressions 2 | 3 | **Expression are something that returns a value** 4 | 5 | - Almost everything is an expression: in Rust. Except _variable bindings_ 6 | 7 | - The "nothing" type is called "unit", which is written `()`. 8 | - The _type_ `()` has only one value: `()`. 9 | - `()` is the default return type. 10 | - Discard an expression's value by appending a semicolon. Now it returns `()`. 11 | - Hence, if a function ends in a semicolon, it returns `()`. 12 | 13 | ```rust 14 | fn foo() -> i32 { 5 } 15 | fn bar() -> () { () } 16 | fn baz() -> () { 5; } 17 | fn qux() { 5; } 18 | ``` 19 | 20 | - Because everything is an expression, we can bind many things to variable names: 21 | 22 | ```rust 23 | let x = -5; 24 | let y = if x > 0 { "greater" } else { "less" }; 25 | println!("x = {} is {} than zero", x, y); 26 | ``` 27 | 28 | - Aside: `"{}"` is Rust's (most basic) string interpolation operator 29 | - like `printf`'s `"%s"` in C/C++. 30 | -------------------------------------------------------------------------------- /3.function/README.md: -------------------------------------------------------------------------------- 1 | ## function 2 | 3 | In Rust we create a function starts with keyword `fn`. 4 | 5 | ```rust 6 | fn add(x: u64, y: u64) -> u64 { 7 | return x + y; 8 | } 9 | ``` 10 | 11 | types of each passed parameters are mentioned on the right side after `:` inside `()`. 12 | 13 | `return` type is specified using `->`, followed by type name. Omit this if nothing gets returned. 14 | **If nothing is returned an `()` UNIT type is returned by default**. 15 | 16 | Function are also `type` in Rust (first class function behaviour(alike in python)). 17 | type of add: `fn(u64, u64)->u64`. 18 | 19 | IMPORTANT: **ALL PASSED PARAMETERS ARE ALSO `IMMUTABLE` BY DEFAULT** if `mut` is not specified explicitly. -------------------------------------------------------------------------------- /3.function/func.rs: -------------------------------------------------------------------------------- 1 | fn add(x: u64, y: u64) -> u64 { 2 | return x + y; 3 | } 4 | 5 | fn main() { 6 | let x: u64 = 20; 7 | let y: u64 = 30; 8 | let result = add(x, y); 9 | println!("result: {}", result); 10 | } 11 | -------------------------------------------------------------------------------- /4.Closures/README.md: -------------------------------------------------------------------------------- 1 | ## Closures 2 | 3 | > function without name but have information about the scope where decalared. 4 | 5 | ```rust 6 | let simple_closure = || (); 7 | ``` 8 | 9 | `||` decalares what parameters we can pass. In simple closure we are taking no parameters. 10 | 11 | `()` is unit type, that means no return. See 3.functions. 12 | 13 | ```rust 14 | fn main() { 15 | let add_closure = |x, y| x + y; 16 | println!("{}", add_closure(3, 7)); 17 | let even_odd_closure = |x: u64| { 18 | if x % 2 != 0 { 19 | return "odd"; 20 | } 21 | return "even"; 22 | }; 23 | println!("{}", even_odd_closure(12)); 24 | println!("{}", even_odd_closure(11)); 25 | } 26 | ``` 27 | -------------------------------------------------------------------------------- /4.Closures/closure.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let add_closure = |x, y| x + y; 3 | println!("{}", add_closure(3, 7)); 4 | let even_odd_closure = |x: u64| { 5 | if x % 2 != 0 { 6 | return "odd"; 7 | } 8 | return "even"; 9 | }; 10 | println!("{}", even_odd_closure(12)); 11 | println!("{}", even_odd_closure(11)); 12 | } 13 | -------------------------------------------------------------------------------- /5.strings/README.md: -------------------------------------------------------------------------------- 1 | ## Strings in Rust 2 | 3 | To `&str` or `String`. ? (⊙.☉)7 4 | 5 | 1. Rust strings are valid UTF-8 encoded byte sequences. 6 | 7 | 2. `&` is an **operator**. It creates a pointer to any type. 8 | That means `&str` types are usually a pointer to some existing string. What is the location of this existing string? It can be anywhere on *heap*, *stack* etc. It depends. 9 | 10 | 3. `String` types are allocated on **heap**. 11 | 12 | How do we differentiate between these two types ? 13 | 14 | Depend's upon initialization. 15 | 16 | ### `&str` type initialization 17 | ```rust 18 | let amp_str_type = "amp_str_type"; 19 | ``` 20 | 21 | ### `String` type initialization. 22 | 23 | ```rust 24 | let name: String = "ankur".to_string(); 25 | let last_name = String::from("anand"); 26 | ``` -------------------------------------------------------------------------------- /5.strings/string.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let amp_str_type = "amp_str_type"; 3 | let name: String = "ankur".to_string(); 4 | let last_name = String::from("anand"); 5 | println!("{}, {}, {}", amp_str_type, name, last_name); 6 | } -------------------------------------------------------------------------------- /6.If-else/README.md: -------------------------------------------------------------------------------- 1 | ## If else 2 | 3 | ### `if` `else` is not an Statement in Rust. It's an expression. 4 | 5 | **So it always returns an value** 6 | 7 | ```rust 8 | fn main() { 9 | let is_ture = true; 10 | if is_ture { 11 | println!("isTure"); 12 | } else { 13 | println!("isFalse"); 14 | } 15 | } 16 | ``` 17 | 18 | So the above `if` and `else` will evaluate the condition while executing all instruction contained inside block evaluating to true and return an `empty () unit type` 19 | 20 | **Both `if` `else` branch should return the same type** 21 | 22 | ```rust 23 | fn main() { 24 | let is_ture = true; 25 | let if_else_result = if is_ture { 26 | "Hello isTure" 27 | } else { 28 | "Hello isFalse" 29 | }; 30 | println!("{}", if_else_result); 31 | } 32 | ``` 33 | -------------------------------------------------------------------------------- /6.If-else/ifelse.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let is_ture = true; 3 | if is_ture { 4 | println!("isTure"); 5 | } else { 6 | println!("isFalse"); 7 | }; 8 | 9 | let if_else_result = if is_ture { 10 | "Hello isTure" 11 | } else { 12 | "Hello isFalse" 13 | }; 14 | println!("{}", if_else_result); 15 | } 16 | -------------------------------------------------------------------------------- /7.Match/README.md: -------------------------------------------------------------------------------- 1 | ## Match expressions 2 | 3 | **switch on steroids** 4 | 5 | - match takes an expression (x) and branches on a list of value => expression statements. so all the expressions within the `match` block is known as **match arms** 6 | 7 | ```rust 8 | fn http_status() -> u16 { 9 | 500 10 | } 11 | 12 | fn main() { 13 | let status = http_status(); 14 | match status { 15 | // all the expressions 16 | 500 => println!("Internal Server Error Status {}", status), 17 | 200 => println!("Yay Got [{}]", status), 18 | _ => println!("ingnore value {}", status), 19 | } 20 | } 21 | ``` 22 | 23 | - Block after `=>` are also expressions in rust and must return the same type. When nothing is returned by default an Unit Type `()` is returned. i.e 24 | 25 | > The entire match evaluates to one expression. Like if, all arms must evaluate to the same type. 26 | 27 | - `_` is commonly used as a catch-all 28 | 29 | - The matched expression can be any expression (l-value), including tuples and function calls. 30 | 31 | ```rust 32 | fn main() { 33 | 34 | let x = 3; 35 | let y = -3; 36 | 37 | match (x, y) { 38 | (1, 1) => println!("one"), 39 | (2, j) => println!("two, {}", j), 40 | (_, 3) => println!("three"), 41 | (i, j) if i > 5 && j < 0 => println!("On guard!"), 42 | (_, _) => println!(":<"), 43 | } 44 | } 45 | ``` 46 | 47 | - Matches can bind variables. `_` is a throw-away variable name. 48 | - it should be an exhaustive match in order to compile. 49 | - if-guards to constrain a match to certain conditions. 50 | -------------------------------------------------------------------------------- /7.Match/match.rs: -------------------------------------------------------------------------------- 1 | fn http_status() -> u16 { 2 | 500 3 | } 4 | fn main() { 5 | let status = http_status(); 6 | match status { 7 | // all the expressions 8 | 500 => println!("Internal Server Error Status {}", status), 9 | 200 => println!("Yay Got [{}]", status), 10 | _ => println!("ingnore value {}", status), 11 | } 12 | 13 | let x = 3; 14 | let y = -3; 15 | 16 | match (x, y) { 17 | (1, 1) => println!("one"), 18 | (2, j) => println!("two, {}", j), 19 | (_, 3) => println!("three"), 20 | (i, j) if i > 5 && j < 0 => println!("On guard!"), 21 | (_, _) => println!(":<"), 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2019, Ankur Anand 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Five minutes Rust 2 | 3 | Rust concise 5 Minutes cheat-sheet for each concepts. 4 | 5 | --- 6 | 7 | ## Hello, Rust! 8 | 9 | ```rust 10 | fn main() { 11 | println!("Hi There!{}", "Ankur Anand"); 12 | } 13 | ``` 14 | 15 | **Important `println!` is not an function. It's a macro in rust. (macro end with `!`)** 16 | 17 | --- 18 | 19 | ## Macros! 20 | 21 | - Macros are like functions, but they're named with `!` at the end. 22 | - Can do generally very powerful stuff. 23 | - They actually generate code at compile time! 24 | - Think macro in `c` but more hygienic. More later! 25 | - Call and use macros like functions. 26 | - You can define your own with `macro_rules! macro_name` blocks. 27 | - These are _very_ complicated. More later! 28 | - Because they're so powerful, a lot of common utilities are defined as macros. 29 | - **println! macro** 30 | 31 | ### `print!` & `println!` 32 | 33 | - Print stuff out. Yay. 34 | - Use `{}` for general string interpolation, and `{:?}` for debug printing. 35 | - Some types can only be printed with `{:?}`, like arrays and `Vec`s. 36 | 37 | ```rust 38 | print!("{}, {}, {}", "foo", 3, true); 39 | // => foo, 3, true 40 | println!("{:?}, {:?}", "foo", [1, 2, 3]); 41 | // => "foo", [1, 2, 3] 42 | ``` 43 | 44 | --- 45 | 46 | ### `format!` 47 | 48 | - Uses `println!`-style string interpolation to create formatted `String`s. 49 | 50 | ```rust 51 | let fmted = format!("{}, {:x}, {:?}", 12, 155, Some("Hello")); 52 | // fmted == "12, 9b, Some("Hello")" 53 | ``` 54 | 55 | --- 56 | 57 | ## Variable Bindings 58 | 59 | How to store a value and refer it later ? 60 | 61 | In rust we can decalare a variable with `let` keyword. i.e Variables are bound with `let` 62 | 63 | ```rust 64 | let name = "ankur"; 65 | ``` 66 | 67 | - Bindings are implicitly-typed: the compiler infers based on context. 68 | - The compiler can't always determine the type of a variable, so sometimes you have to add type annotations. 69 | 70 | ```rust 71 | let x: i16 = 9; 72 | ``` 73 | 74 | > All the variables are **immutable** by **default** in Rust. i.e Once the variable has been decalared and initialized, you cannot assign some other value to it by default. 75 | 76 | Trying to reassign will throw you an error at compile time. 77 | 78 | ```rust 79 | fn main() { 80 | let x_immutable = 10; 81 | println!("x value : {}", x_immutable); 82 | x_immutable = 20; 83 | } 84 | ``` 85 | 86 | ```sh 87 | error[E0384]: cannot assign twice to immutable variable `x_immutable` 88 | --> var.rs:4:5 89 | | 90 | 2 | let x_immutable = 10; 91 | | ----------- first assignment to `x_immutable` 92 | 3 | println!("x value : {}", x_immutable); 93 | 4 | x_immutable = 20; 94 | | ^^^^^^^^^^^^^^^^ cannot assign twice to immutable variable 95 | ``` 96 | 97 | So if We want to reassign variable to some other value, add `mut` keyword before it. 98 | 99 | ```rust 100 | fn main() { 101 | let mut y_mutable = 20; 102 | println!("y mut {}", y_mutable); 103 | y_mutable = 30; 104 | println!("y mut {}", y_mutable); 105 | } 106 | ``` 107 | 108 | - Bindings may be shadowed: 109 | 110 | ```rust 111 | let x = 17; 112 | let y = 53; 113 | let x = "Shadowed!"; 114 | // x is not mutable, but we're able to re-bind it 115 | ``` 116 | 117 | - The shadowed binding for `x` above lasts until it goes out of scope. 118 | - Above, we've effectively lost the first binding, since both `x`s are in the same scope. 119 | 120 | - Patterns may also be used to declare variables: 121 | 122 | ```rust 123 | let (a, b) = ("foo", 12); 124 | ``` 125 | 126 | --- 127 | 128 | ## Expressions 129 | 130 | **Expression are something that returns a value** 131 | 132 | - Almost everything is an expression: in Rust. Except _variable bindings_ 133 | 134 | - The "nothing" type is called "unit", which is written `()`. 135 | - The _type_ `()` has only one value: `()`. 136 | - `()` is the default return type. 137 | - Discard an expression's value by appending a semicolon. Now it returns `()`. 138 | - Hence, if a function ends in a semicolon, it returns `()`. 139 | 140 | ```rust 141 | fn foo() -> i32 { 5 } 142 | fn bar() -> () { () } 143 | fn baz() -> () { 5; } 144 | fn qux() { 5; } 145 | ``` 146 | 147 | - Because everything is an expression, we can bind many things to variable names: 148 | 149 | ```rust 150 | let x = -5; 151 | let y = if x > 0 { "greater" } else { "less" }; 152 | println!("x = {} is {} than zero", x, y); 153 | ``` 154 | 155 | - Aside: `"{}"` is Rust's (most basic) string interpolation operator 156 | - like `printf`'s `"%s"` in C/C++. 157 | --------------------------------------------------------------------------------