Rust concepts
2024-08-22

Rust concepts explained simply.

Table of Contents

# Borrow Checker

Ownership:

prevents double free, accessing memory after free and ensuring memory safety

Borrowing:

prevents aliasing and data races. ensure single writer and multiple writes.

Lifetimes:

prevents invalid or dangling references. ensures that references remain valid and dont outlive the data they point to.

# Shared mutability/ownership

cell (shared mutability) vs rc (shared ownership) vs sync (synchronization)

cell: shared mutability

// assert_eq!(min_path(&[&[1, 2], &[3, 4]]), 3);
let cell = Cell::new(3);
assert_eq!(cell.get(), 3); // duplicate inner value
assert_eq!(cell.take(), 3); // take and replace with default value
assert_eq!(cell.get(), 0); // assert default value
// RefCell::replace()
// RefCell::swap()
// RefCell::borrow()
// RefCell::borrow_mut()

use std::cell::RefCell;

#[derive(Debug)]
struct NoCopyu32(u32);

let ref_cell = RefCell::new(NoCopyu32(3));
let num: &NoCopyu32 = &ref_cell.borrow();
assert_eq!(num.0, 3);

let num_mut: &mut NoCopyu32 = &mut ref_cell.borrow_mut();
num_mut.0 = 4;
assert_eq!(num.0, 4);

rc: shared ownership

use std::rc::Rc;

#[derive(Debug)]
struct NoCopyu32(u32);

let rc = Rc::new(NoCopyu32(3));
let clone = rc.clone();

assert!(Rc::ptr_eq(&rc, &clone));
assert!(rc.0 == clone.0);
assert!(Rc::strong_count(&rc) == 2);

let rc_other = Rc::new(NoCopyu32(3));
assert!(rc.0 == rc_other.0);
assert!(!Rc::ptr_eq(&rc, &rc_other));

sync

# Async

Send:

todo

Sync:

https://doc.rust-lang.org/nomicon/send-and-sync.html https://doc.rust-lang.org/std/marker/trait.Send.html https://doc.rust-lang.org/std/marker/trait.Sync.html

Types which are safe to share references between threads.

Auto Impl impl Sync for Arc impl<T: ?Sized + Send> Sync for Mutex<T>

The precise definition is: a type T is Sync if and only if &T is Send. In other words, if there is no possibility of undefined behavior (including data races) when passing &T references between threads.

A shorter overview of how Sync and Send relate to referencing:

  • &T is Send if and only if T is Sync
  • &mut T is Send if and only if T is Send
  • &T and &mut T are Sync if and only if T is Sync

Future/Task:

Check out the dedicated post on Futures: https://toidiu.com/blog/rust-future-ecosystem/

Pin:

Definition of “pinning"

“Pinning” allows us to put a value which exists at some location in memory into a state where safe code cannot move that value to a different location in memory or otherwise invalidate it at its current location

Unpin

The vast majority of Rust types have no address-sensitive states. These types implement the Unpin auto-trait, which cancels the restrictive effects of Pin when the pointee type T is Unpin.

When T: Unpin, Pin<Box> functions identically to a non-pinning Box; similarly, Pin<&mut T> would impose no additional restrictions above a regular &mut T.

# Traits

Deref:

todo

Drop:

todo

PhantomData:

todo