created on 2020-08-29, edited on 2021-06-13

Learning Rust

Here is a list of stuff that I find interesting and important while trying to learn the Rust Language.

Variables

Variables are often calleed bindings in Rust. It makes sense since by default variables are immutable in Rust. Any variable that goes out of scope is dropped. Dropping means releasing the resources that are tied(bound) to that variable. Only one thing can own a piece of data at a time in Rust.

A small note about lifetimes

struct MyStruct<'lifetime>(&'lifetime str);

This annotation means that the lifetime of MyStruct can not outlive the reference that holds in its fields

into_iter, iter and iter_mut

Arrays

An array can be defined in two ways:

Option

Option enum is used when the absence of a value is a possibility, known as null reference in some other languages. The two examples below are identical, a good explanation for if let

// 1
let some_number: Option = Some(7);
match some_number {
    Some(7) => println!("That's my lucky number!"),
    _ => {},
}
// 2
let some_number: Option = Some(7);
if let Some(7) = some_number {
    println!("That's my lucky number!");
}

Traits

Two ways of having trait bounds

// 1
fn fn_one(value: &impl Trait) { ... }
// 2
fn fn_two<T: Trait>(value: &T) { ... }

Iterator trait looks like this in Rust standard library One interesting thing is 'type Item'. It means every implementation of Iterator should return an associated type Item.

trait Iterator {
    type Item;
    fn next(&mut self) -> Option<Self::Item>;
}

(?) syntax sugar

(?) is used to propagate errors. The two functions below are equivalent.

fn function_1() -> Result(Success, Failure) {
	match operation_that_might_fail() {
		Ok(success) => success,
		Err(failure) => return Err(failure),
	}
}

fn function_2() -> Result(Success, Failuer) {
	operation_that_might_fail()?
}

Fun topic about string literals https://doc.rust-lang.org/reference/tokens.html#raw-string-literals

Conditional Compilation for Debug and Release Builds

Here is a way to conditionally compile Rust code for Debug and Release builds

#[cfg(debug_assertions)]
fn example() {
    println!("Debugging enabled");
}

#[cfg(not(debug_assertions))]
fn example() {
    println!("Debugging disabled");
}

fn main() {
    if cfg!(debug_assertions) {
        println!("Debugging enabled");
    } else {
        println!("Debugging disabled");
    }

    #[cfg(debug_assertions)]
    println!("Debugging enabled");

    #[cfg(not(debug_assertions))]
    println!("Debugging disabled");

    example();
}