// 1. Raw pointer dereference
fn main() {
let x = 42;
let p: *const i32 = &x;
unsafe {
println!("via raw ptr: {}", *p);
}
// 2. Calling an unsafe function (e.g. FFI)
unsafe {
let n = libc::abs(-7); // requires the `libc` crate
println!("abs = {n}");
}
// 3. Safe abstraction over unsafe — the standard pattern
let v = vec![10u32, 20, 30, 40];
let first_two = unsafe { std::slice::from_raw_parts(v.as_ptr(), 2) };
println!("{first_two:?}"); // [10, 20]
}
// Don't:
// - Use unsafe to silence the borrow checker (the compiler is usually right)
// - Touch raw pointers when a safe wrapper exists
// Do:
// - Confine `unsafe` blocks to the smallest scope
// - Document INVARIANTS the caller must uphold for the unsafe API
Create a free account and build your private vault. Share publicly whenever you want.