[Rust](https://www.rust-lang.org/) is a statically-typed programming language known for its emphasis on performance, safety, and concurrency. Originally developed by [Mozilla](../../../internet/websites/clearnet/Mozilla.md), Rust has gained popularity for its ability to provide low-level control over system resources without sacrificing memory safety. Rust uses [Cargo](../../../applications/development/cargo.md) as its package manager and build tool.
Your application starts within the main function, so the simplest application is this:
```rust
fn main() {
}
```
### Variables
You can declare variables. Variables are immutable by default, if you need to change them you have to use the `mut` keyword. Every variable is strongly typed, but you can either ommit type information and let the compiler infer the type or explicitly state it. Constants which never change can be made as well.
```rust
let var = "Hello";
let mut mutable = "World";
let explicit_num: isize = 0;
const NINE_K: isize = 9000;
```
### Data Types & Ownership
Every variable in Rust is strongly typed. You can define your own types and use the compiler together with an algebraic type system to your advantage.
In Rust, primitive types are classified into two categories: scalar types and compound types:
One can use functions with optional arguments and return types. If you `return` on the last line, you can ommit the `return` keyword and `;` to return the value.
```rust
fn printHello() {
println!("Hello");
}
fn greet(name: &str) {
println!("Hello {name}");
}
fn add_two(a: isize) -> isize {
a + 2 // same as "return a + 2;"
}
```
### Enums
Rust has enums which can even hold some data.
```rust
enum StatusCode {
NOT_FOUND,
OK,
Err(String)
}
let err_response = StatusCode::Err(String::from("Internal Error"));
Rust has support for comments. There are regular comments, multiline comments and documentation comments. Documentation comments get used when generating documation via `cargo doc` and inside the IDE.
```rust
// This is a comment
/*
This
is multiline
comment
*/
/// This function does something.
/// Documentation comments can be styled with markdown as well.
///
/// # Example
///
/// If you place a rust code block here, you can provide examples on how to use this function and `cargo test` will automatically run this code block when testing.
fn do_something() {
}
```
### Modules
You can split your code up into multiple modules for better organization.
```rust
// will search for `mymod.rs` or `mymod/mod.rs` beside the source file and include it as `mymod`;
mod mymod;
// inline module
mod processor {
struct AMD {
name: String
}
}
fn main() {
// full syntax
let proc = processor::AMD{ name: "Ryzen".to_string() };
// you can put often used symbols in scope
use processor::AMD;
let proc = AMD{ name: "Ryzen".to_string() };
}
```
### Generics
Generics let you write code for multiple data types without repeating yourself. Instead of an explicit data type, you write your code around a generic type.
```rust
struct Point<T> {
x: T,
y: T,
}
impl<T> Point<T> {
fn x(&self) -> &T {
&self.x
}
}
// you can declare methods which only work for specific data types.
-`Add`, `Sub`, `Mul`, and `Div`: Traits for arithmetic operations.
```rust
pub trait Add<RHS=Self> {
type Output;
fn add(self, rhs: RHS) -> Self::Output;
}
// Similar traits for Sub, Mul, and Div
```
### Closures
Closures are anonymous functions. They can be assigned to variables, passed as parameters or returned from a function.
```rust
fn add_one_v1 (x: u32) -> u32 { x + 1 }
let add_one_v2 = |x: u32| -> u32 { x + 1 };
let add_one_v3 = |x| { x + 1 };
let add_one_v4 = |x| x + 1 ;
// this function takes ownership over variables it uses as noted by `move`
thread::spawn(
move || println!("From thread: {:?}", list)
).join().unwrap();
// To use closures as parameters, specify the type. It is one of the Fn traits
impl<T> Option<T> {
pub fn unwrap_or_else<F>(self, f: F) -> T
where
F: FnOnce() -> T
{
match self {
Some(x) => x,
None => f(),
}
}
}
```
### Iterators
The [iterator pattern](../patterns/behavioral/Iterator%20Pattern.md) allows you to perform some task on a sequence of items in turn. An iterator is responsible for the logic of iterating over each item and determining when the sequence has finished. When you use iterators, you don’t have to reimplement that logic yourself.
```rust
let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();
```
With this you can do functional programming with the iterators.
Some functions on them include:
-`chain(other)`: An iterator that links two iterators together, in a chain.
-`cloned()`: An iterator that clones the elements of an underlying iterator.
-`copied()`: An iterator that copies the elements of an underlying iterator.
-`cycle()`: An iterator that repeats endlessly.
-`empty()`: An iterator that yields nothing.
-`enumerate()`: An iterator that yields the current count and the element during iteration.
-`filter(predicate)`: An iterator that filters the elements of `iter` with `predicate`.
-`filterMap(f)`: An iterator that uses `f` to both filter and map elements from `iter`.
-`flat_map(f)`: An iterator that maps each element to an iterator, and yields the elements of the produced iterators.
-`flatten()`: An iterator that flattens one level of nesting in an iterator of things that can be turned into iterators.
-`from_fn(f)`: An iterator where each iteration calls the provided closure `F: FnMut() -> Option<T>`.
-`fuse()`: An iterator that yields `None` forever after the underlying iterator yields `None` once.
-`inspect(f)`: An iterator that calls a function with a reference to each element before yielding it.
-`map(f)`: An iterator that maps the values of `iter` with `f`.
-`map_while(f)`: An iterator that only accepts elements while `predicate` returns `Some(_)`.
-`once(value)`: An iterator that yields an element exactly once.
-`peekable()`: An iterator with a `peek()` that returns an optional reference to the next element.
-`repeat(value)`: An iterator that repeats an element endlessly.
-`rev()`: A double-ended iterator with the direction inverted.
-`skip(n)`: An iterator that skips over `n` elements of `iter`.
-`skip_while(f)`: An iterator that rejects elements while `predicate` returns `true`.
-`step_by(n)`: An iterator for stepping iterators by a custom amount.
-`successors(first, f)`: A new iterator where each successive item is computed based on the preceding one.
-`take(n)`: An iterator that only iterates over the first `n` iterations of `iter`.
-`take_while(f)`: An iterator that only accepts elements while `predicate` returns `true`.
-`zip(a, b)`: An iterator that iterates two other iterators simultaneously.
### Standard Library
Rust, a systems programming language known for its focus on safety and performance, comes with a rich standard library that provides a wide range of modules to handle common tasks.
1.**`std::collections`**: Data structures like `Vec`, `HashMap`, etc.
2.**`std::fs`**: File system manipulation and I/O operations.
3.**`std::thread`**: Facilities for concurrent programming with threads.
4.**`std::time`**: Time-related types and functionality.
5.**`std::io`**: Input and output facilities.
6.**`std::path`**: Path manipulation utilities.
7.**`std::env`**: Interface to the environment, command-line arguments, etc.
20.**`std::marker`**: Marker traits for influencing Rust's type system.
## Macros
We’ve used macros like `println!` before, but we haven’t fully explored what a macro is and how it works. The term _macro_ refers to a family of features in Rust: _declarative_ macros with `macro_rules!` and three kinds of _procedural_ macros:
- Custom `#[derive]` macros that specify code added with the `derive` attribute used on structs and enums
- Attribute-like macros that define custom attributes usable on any item
- Function-like macros that look like function calls but operate on the tokens specified as their argument
Fundamentally, macros are a way of writing code that writes other code, which is known as _metaprogramming_. All of these macros _expand_ to produce more code than the code you’ve written manually.
Declarative macros work almost like a `match` statement.
```rust
macro_rules! mymacro {
($expression:expr) => {
println!("{}", $expression)
};
($expression:expr, $other:expr) => {
println!("{} {}", $expression, $other)
};
}
mymacro!("Hello World");
mymacro!("Hello", "World");
```
This macro gets expanded to the code inside the `macro_rules!` section with the provided arguments. For more information on macros, see the [docs](https://doc.rust-lang.org/reference/macros-by-example.html).
Rust is focused strongly on safety, but sometimes doing something dangerous is necessary. In this case you can use the `unsafe` keyword. `unsafe` should be used only when needed as it may cause undefinied behaviour, but when debugging you can solely focus on your `unsafe` blocks as all potential dangerous operations are neatly packaged in them.
There are two types of using `unsafe`:
-`unsafe` blocks lets you call dangerous code. With this you can wrap unsafe code in a safe function with checks to call.
```rust
fn write_to_serial(data: &[u8]) {
assert!(data.is_valid());
unsafe {
// doing potentially unsafe things
write_to_serial_unchecked(data);
}
}
```
-`unsafe` functions can only be called from `unsafe` blocks.
- [image](https://lib.rs/crates/image): Imaging library. Provides basic image processing and encoders/decoders for common image formats.
### CLI
- [rustyline](https://lib.rs/crates/rustyline): Rustyline, a readline implementation based on Antirez's Linenoise
- [clap](https://lib.rs/crates/clap): A simple to use, efficient, and full-featured Command Line Argument Parser
- [crossterm](https://lib.rs/crates/crossterm): A crossplatform terminal library for manipulating terminals
- [indicatif](https://lib.rs/crates/indicatif): A progress bar and cli reporting library for Rust
- [argh](https://lib.rs/crates/argh): Derive-based argument parser optimized for code size
- [owo-colors](https://lib.rs/crates/owo-colors): Zero-allocation terminal colors that'll make people go owo
- [yansi](https://lib.rs/crates/yansi): A dead simple ANSI terminal color painting library
### Compression
- [flate2](https://lib.rs/crates/flate2): DEFLATE compression and decompression exposed as Read/BufRead/Write streams. Supports miniz_oxide and multiple zlib implementations. Supports zlib, gzip, and raw deflate streams.
- [zstd](https://lib.rs/crates/zstd): Binding for the zstd compression library
- [unrar](https://lib.rs/crates/unrar): list and extract RAR archives
### Databases
- [rusqlite](https://lib.rs/crates/rusqlite): Ergonomic wrapper for [SQLite](../SQLite.md)
- [sqlx](https://lib.rs/crates/sqlx): The Rust [SQL](SQL.md) Toolkit. An async, pure Rust [SQL](SQL.md) crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, and [SQLite](../SQLite.md).
- [regex](https://lib.rs/crates/regex): An implementation of [regular expressions](../../../tools/Regex.md) for Rust. This implementation uses finite automata and guarantees linear time matching on all inputs.
- [comfy-table](https://lib.rs/crates/comfy-table): An easy to use library for building beautiful tables with automatic content wrapping
- [similar](https://lib.rs/crates/similar): A diff library for Rust
### Concurrency
- [parking_lot](https://lib.rs/crates/parking_lot): More compact and efficient implementations of the standard synchronization primitives
- [crossbeam](https://lib.rs/crates/crossbeam): Tools for concurrent programming
- [rayon](https://lib.rs/crates/rayon): Simple work-stealing parallelism for Rust
### Async
- [tokio](https://lib.rs/crates/tokio): An event-driven, non-blocking I/O platform for writing asynchronous I/O backed applications
- [futures](https://lib.rs/crates/futures): An implementation of futures and streams featuring zero allocations, composability, and iterator-like interfaces