Rust terminology
Jump to navigation
Jump to search
Introduction
Just a page to remind myself of
Rust Terminology Cheat Sheet
Term | Meaning | Example | Notes |
---|---|---|---|
Move | Transfer ownership of a value | let b = a; — a is moved into b
|
After move, a is invalid unless Copy
|
Copy | Duplicate value without invalidating original | let y = x; where x: u32
|
Only types that implement Copy (e.g. primitives)
|
Borrow | Create a reference to a value | let r = &x; or let r = &mut x;
|
No ownership transfer; enforces lifetimes |
Replace | Swap a value behind a reference | std::mem::replace(&mut x, new_val)
|
Moves out old value, inserts new one |
Take | Replace with default, return old value | std::mem::take(&mut x)
|
Requires Default trait
|
Drop | Explicitly destroy a value | drop(x)
|
Frees resources early |
Pin | Prevent a value from being moved | let pinned = Box::pin(my_val)
|
Needed for self-referential types, Future , etc.
|
Unpin | Marker trait: safe to move even if pinned | Most types are Unpin by default
|
Opt out with impl !Unpin for T {}
|
Destructure | Break a value into its components | let (a, b) = tuple; or let Struct { x, y } = s;
|
Can trigger moves if fields aren’t Copy
|
Ownership | Who is responsible for freeing a value | let x = String::from("hi");
|
Ownership moves unless borrowed |
Smart Pointer | Wrapper that manages ownership/lifetime | Box<T> , Rc<T> , Arc<T> , RefCell<T>
|
Each has different semantics |
Interior Mutability | Mutate through shared reference | RefCell<T> , Mutex<T>
|
Enables mutation behind &
|
Self-referential | Struct with internal pointers to its own fields | struct S { buf: Vec<u8>, ptr: *const u8 }
|
Needs Pin to be safe
|
Map in place | Transform a value behind a mutable reference | Unsafe: ptr::read + ptr::write combo
|
Can cause double-drop on panic |
Example: Replace vs Move
struct T { s: String }
fn main() {
let mut t = T { s: "hello".to_string() };
// ❌ Can't move out of `t.s` directly
// let new_t = T { s: t.s + " world" };
// ✅ Use replace
let old = std::mem::replace(&mut t, T { s: String::new() });
t.s = old.s + " world";
}
🧠 Note on "Nottoe"
If "Nottoe" refers to "not to move" or a shorthand for immovable types, it may relate to:
!Unpin
typesDrop
-guarded valuesPin<&mut T>
where movement is forbidden
Let me know if you'd like to expand this glossary with macro patterns or visual memory layout diagrams.
📌 Idiomatic Pin Usage Patterns
Pinning is essential when working with self-referential types, async state machines, or anything requiring memory stability. This page outlines safe patterns, macro ergonomics, and common pitfalls.
🔒 Why Use Pin?
- Prevents movement of values after initialization
- Guarantees memory address stability
- Required for types that hold internal references or rely on layout
✅ Safe Pin Construction
// Heap-allocate and pin
let pinned = Box::pin(MyType::new());
- Use
Box::pin
for heap allocation - Avoid
Pin::new
unless you control the lifetime and layout
🧰 Accessing Fields Safely
Use Pin::as_mut
and Pin::map
to access fields without moving:
impl MyType {
fn poll_self(mut self: Pin<&mut Self>) {
let field = self.as_mut().map(|s| &mut s.field);
// Use field safely
}
}
⚠️ Avoiding Moves
Never do this:
// ❌ Moves out of pinned value
let inner = *pinned;
Instead, use references or safe projections.
🧠 Macro Ergonomics for Pin
Define macros to reduce boilerplate and enforce pin-safe access:
macro_rules! pin_project {
($self:ident => $field:ident) => {
$self.as_mut().map(|s| &mut s.$field)
};
}
Usage:
fn poll(mut self: Pin<&mut Self>) {
let buf = pin_project!(self => buffer);
// Use buf safely
}
🧪 Example: Self-Referential Future
<syntaxhighlight lang="rust"> struct MyFuture {
buffer: Vec<u8>, ptr: *const u8, // points into buffer
}
impl Future for MyFuture {
type Output = ();
fn poll(mut self: Pin<&mut Self>, _: &mut Context