# Rust Smart Pointer Cheatsheet
Rust's smart pointers enhance the ownership model, providing additional functionality for memory management. Below is a concise reference for the most common smart pointers, their purposes, use cases, and examples.
## Summary Table
| Smart Pointer | Description | Use Cases | Example |
|---------------|-------------|-----------|---------|
| `Box<T>` | Heap-allocated value with single ownership | Large data, recursive types | `let x = Box::new(5);` |
| `Rc<T>` | Reference-counted pointer for shared ownership (single-threaded) | Graphs, multiple owners | `let a = Rc::new(5); let b = Rc::clone(&a);` |
| `Arc<T>` | Atomic reference-counted pointer for shared ownership (multi-threaded) | Cross-thread data sharing | `let a = Arc::new(5); let b = Arc::clone(&a);` |
| `RefCell<T>` | Interior mutability with runtime borrow checking | Mutating data in immutable contexts | `let x = RefCell::new(5); *x.borrow_mut() = 10;` |
| `Mutex<T>` | Mutual exclusion for shared mutable state (multi-threaded) | Synchronizing access to shared data | `let m = Mutex::new(5); *m.lock().unwrap() = 10;` |
| `RwLock<T>` | Read-write lock for multiple readers or one writer | Efficient concurrent access with more reads than writes | `let lock = RwLock::new(5); let r = lock.read().unwrap();` |
| `Cell<T>` | Interior mutability for `Copy` types | Simple mutable state without borrow checking | `let c = Cell::new(5); c.set(10);` |
## Key Points
- **Purpose**: Smart pointers extend Rust's ownership system with features like heap allocation, shared ownership, and mutability control.
- **Deref Trait**: Most implement `Deref`, allowing use of `*` or direct method calls on the underlying data.
- **Drop Trait**: Automatically handles cleanup (e.g., deallocation) when the smart pointer goes out of scope.
- **Selection**: Choose based on ownership needs (single vs. multiple), thread safety, and mutability requirements.
- **Overhead**: Be aware of runtime costs like reference counting (`Rc<T>`, `Arc<T>`), runtime borrow checks (`RefCell<T>`), or locking (`Mutex<T>`, `RwLock<T>`).
## Usage Examples
### `Box<T>`
```rust
let x = Box::new(5); // Allocates 5 on the heap
println!("{}", *x); // Prints: 5
```
### `Rc<T>`
```rust
use std::rc::Rc;
let a = Rc::new(5);
let b = Rc::clone(&a);
println!("{}, {}", a, b); // Prints: 5, 5
```
### `Arc<T>`
```rust
use std::sync::Arc;
use std::thread;
let a = Arc::new(5);
let b = Arc::clone(&a);
thread::spawn(move || println!("{}", b)).join().unwrap(); // Prints: 5
```
### `RefCell<T>`
```rust
use std::cell::RefCell;
let x = RefCell::new(5);
*x.borrow_mut() = 10;
println!("{}", *x.borrow()); // Prints: 10
```
### `Mutex<T>`
```rust
use std::sync::Mutex;
let m = Mutex::new(5);
{
let mut num = m.lock().unwrap();
*num = 10;
}
println!("{:?}", m); // Prints: Mutex { data: 10 }
```
### `RwLock<T>`
```rust
use std::sync::RwLock;
let lock = RwLock::new(5);
{
let r1 = lock.read().unwrap();
let r2 = lock.read().unwrap();
println!("{}, {}", r1, r2); // Prints: 5, 5
}
```
### `Cell<T>`
```rust
use std::cell::Cell;
let c = Cell::new(5);
c.set(10);
println!("{}", c.get()); // Prints: 10
```
This cheatsheet provides a quick reference for working with Rust smart pointers effectively.