Appearance
Basics
Initializing varaibles
Variables are initialized with let keyword. Variables can optionally have a type declared
rust
let a = 3;
let b: i32 = 3;Variables initialised by let keyword are not mutatble. We have to use mut keyword to make the variables mutable.
rust
let mut a = 3;
a = 4;Rust also provides const keyword to initialize global variables that cannot be mutated, the convention is to use capital letters for them. static keyword is used to initialize variables that have fixed memory location for the entire life-cycle of the program const and static need to explicitly state the type
rust
const COUNTER: u32 = 0;
static GLOBAL_COUNTER: u32 = 0;References
References allow you to access a value indirectly.
rust
let x = 5;
let r = &x;Types
Rust provides the following types for numbers: u8 to u128 for unsigned integers, i8 to i128 for signed integers. isize and usize have arch dependent sized. Rust has str and String type for string. This handles utf-8 by default.
Stack vs Heap
The stack stores local values with known size at compile time. The heap stores dynamically allocated data whose size or lifetime is managed at runtime.
Collections
Arrays: These are lists of fixed size that contain items of same type
Tuples: These are lists of fixed size that can hold values of different types
Vectors: These are list which can be extended in size and modified for every item on every index
rust
let arr = [1, 2, 3, 4, 5];
let tup = (1, 2, 3, 4, 5);
let vector = vec![1, 2, 3, 4, 5];Generics
T and E are generic type parameters. Rust will substitute concrete types when the code is compiled.
rust
Vec<T>
Option<T>
Result<T, E>Functions
Function are declared with fn keyword and input and output types need to be specified for every function
rust
fn write_something (mut s: String) -> String {
s.push_str("What ?");
s
}Closures
Closures are unnamed anonymous function
rust
|x| {
2*x
}Compound Types
Enums and Structs are compount types which help us represent complex data types or gather similar data together
rust
struct Cat {
name: String,
weight: u32,
breed: String
}
enum Breeds {
MaineCoon,
Siamese,
Bengal,
Sphynx,
}Implementation
We can add methods to our enums or structs, giving us a sort of class
rust
impl Cat {
pub fn new(name: &str, breed: &str, weight: u32) -> Cat {
Cat {
name: name.to_string(),
weight,
breed: breed.to_string()
}
}
fn is_fat(&self) -> bool {
self.weight > 6
}
}pub keyword is added to make the function/struct/enum public, by defauolt its private
Traits
Traits are methods that define a common funciton that various types can use
rust
trait GetName {
fn get_name(&self) -> String;
}
impl GetName for Cat {
fn get_name(&self) -> String {
self.name.clone()
}
}Attributes
Attributes are compiler directives and metadata attached to Rust items.
rust
#[derive(Debug)]
#[test]
#[allow(dead_code)]
#[cfg(target_os = "linux")]These are some examples, Debug: This allows us to print custom types for debugging PartialEq: This allows us to check equality with custom types allow(dead_code): Prevents warning for unused code
Pattern matching
Like a switch but for Rust. This forces you to check all possible patterns
rust
match value {
1 => println!("one"),
_ => println!("other"),
}_ is used for the case when nothing else matched, the default check.
Option and Result
These are special enums are comonly used to handle ambigous outputs
Option<T> can have Some(T) or None for a response Result<T, E> can have Ok(T) or Err(error) for a response
Error handling
- Matching
rust
// For option
match value {
Some(v) => v,
None => return,
}
// For resut
match value {
Ok(v) => v,
Err(err) => {
println!("Error: {}", err);
return;
}
}?
rust
let result = function()?;This will not panic if there is error but return the error instead to the parent function
Modules
importing module, crates
rust
use::utils::helper::validatorMacros
Macros generate Rust code during compilation.
rust
println!("Write something to console");
vec![1, 2, 3];
panic!("Crash the program at this point");Loops
loop
rust
let mut i = 0;
loop {
if i == 5 {
break;
}
i += 1;
}while
rust
let mut i = 0;
while i <= 5 {
i += 1;
}
3. `for`
```rust
for i in 0..5 {
println!("{}", i);
}
4. Iteratoring over collections
```rust
let list = vec![0, 1, 2, 3];
for item in list {
println!("{}", item);
}Convention
| Item | Convention | Example |
|---|---|---|
| Variables | snake_case | user_name |
| Functions | snake_case | read_file |
| Methods | snake_case | get_name |
| Modules | snake_case | file_utils |
| Crates | snake_case | serde_json |
| Traits | UpperCamelCase | Display |
| Structs | UpperCamelCase | UserAccount |
| Enums | UpperCamelCase | ConnectionState |
| Enum Variants | UpperCamelCase | Connected |
| Type Aliases | UpperCamelCase | UserId |
| Constants | SCREAMING_SNAKE_CASE | MAX_RETRIES |
| Statics | SCREAMING_SNAKE_CASE | GLOBAL_COUNTER |
| Generic Types | Single uppercase letter | T, E, K, V |