Loading...
Loading...
Compare original and translation side by side
Need shared mutation?
YES → Single-threaded or multi-threaded?
Single-threaded → Is T: Copy?
YES → Cell<T> (zero overhead, no borrow tracking)
NO → RefCell<T> (runtime borrow checking, panics on violation)
Multi-threaded → High contention?
NO → Arc<Mutex<T>> (simple, correct)
YES → Arc<RwLock<T>> (many readers, few writers)
or lock-free types (crossbeam, atomic)
NO → Use normal ownership / borrowingNeed shared mutation?
YES → Single-threaded or multi-threaded?
Single-threaded → Is T: Copy?
YES → Cell<T> (zero overhead, no borrow tracking)
NO → RefCell<T> (runtime borrow checking, panics on violation)
Multi-threaded → High contention?
NO → Arc<Mutex<T>> (simple, correct)
YES → Arc<RwLock<T>> (many readers, few writers)
or lock-free types (crossbeam, atomic)
NO → Use normal ownership / borrowing| Type | When to use |
|---|---|
| Recursive types, large stack values, trait objects |
| Single-threaded shared ownership (trees, graphs) |
| Multi-threaded shared ownership |
| Sometimes borrowed, sometimes owned — avoid eager clones |
| Self-referential types, async futures |
| 类型 | 适用场景 |
|---|---|
| 递归类型、大栈值、trait对象 |
| 单线程共享所有权(树、图结构) |
| 多线程共享所有权 |
| 有时借用、有时拥有的场景——避免不必要的 eager 克隆 |
| 自引用类型、异步future |
Cow<str>Cow<[T]>&strCow<str>Cow<[T]>&strthiserroranyhowthiserroranyhow| Context | Crate | Why |
|---|---|---|
| Library crate | | Callers need to match on specific error variants |
| Binary / application | | Errors bubble up to user-facing messages with context |
| Internal modules | | Type-safe error variants for the parent module to handle |
| FFI boundary | Custom enum | Must map to C-compatible error codes |
| 场景 | 依赖Crate | 原因 |
|---|---|---|
| 库crate | | 调用方需要匹配具体的错误变体 |
| 二进制/应用 | | 错误会向上冒泡为带上下文的用户-facing 消息 |
| 内部模块 | | 为父模块提供类型安全的错误变体供处理 |
| FFI边界 | 自定义枚举 | 必须映射为C兼容的错误码 |
?fs::read_to_string(path)
.with_context(|| format!("failed to read config: {path}"))?;#[from]#[derive(thiserror::Error, Debug)]
pub enum DbError {
#[error("connection failed: {0}")]
Connection(#[from] std::io::Error),
#[error("query failed: {reason}")]
Query { reason: String },
}Resultmatchmapmap_errand_thenunwrap_or_elseunwrap()expect()?fs::read_to_string(path)
.with_context(|| format!("failed to read config: {path}"))?;#[from]#[derive(thiserror::Error, Debug)]
pub enum DbError {
#[error("connection failed: {0}")]
Connection(#[from] std::io::Error),
#[error("query failed: {reason}")]
Query { reason: String },
}Resultmatchmapmap_errand_thenunwrap_or_elseunwrap()expect()Need runtime polymorphism (heterogeneous collection, plugin system)?
YES → dyn Trait (Box<dyn Trait> or &dyn Trait)
NO → impl Trait / generics (zero-cost, monomorphized)Need runtime polymorphism (heterogeneous collection, plugin system)?
YES → dyn Trait (Box<dyn Trait> or &dyn Trait)
NO → impl Trait / generics (zero-cost, monomorphized)Iterator::Itemimpl<T: Display> ToString for Ttrait Printable: Debug + DisplayIterator::Itemimpl<T: Display> ToString for Ttrait Printable: Debug + Displaydyn TraitSelfself&self&mut selfdyn Trait + async#[async_trait]Box<dyn Future>dyn TraitSelfself&self&mut selfdyn Trait + async#[async_trait]Box<dyn Future>tokio#[tokio::main]#[tokio::test]tokio::task::spawn_blockingrayontokio#[tokio::main]#[tokio::test]tokio::task::spawn_blockingrayon#[async_trait]#[async_trait]async fndyn Traitasync fndyn Traittokio::spawnSendMutexGuard!Send.await{
let mut guard = lock.lock().unwrap();
guard.push(42);
} // guard dropped
do_async_thing().await; // future is Sendtokio::spawnSend.awaitMutexGuard!Send{
let mut guard = lock.lock().unwrap();
guard.push(42);
} // guard dropped
do_async_thing().await; // future is Send.awaittokio::select!| Operation | Cancel-safe? |
|---|---|
| Yes |
| Yes |
| No |
| No |
tokio::spawnJoinHandletokio_util::sync::CancellationToken.awaittokio::select!| 操作 | 是否取消安全? |
|---|---|
| 是 |
| 是 |
| 否 |
| 否 |
tokio::spawnJoinHandletokio_util::sync::CancellationTokenJoinSetJoinSetlet mut set = tokio::task::JoinSet::new();
for url in urls {
set.spawn(fetch(url));
}
while let Some(result) = set.join_next().await {
result??;
}let mut set = tokio::task::JoinSet::new();
for url in urls {
set.spawn(fetch(url));
}
while let Some(result) = set.join_next().await {
result??;
}UserIdOrderIdstruct UserId(u64);
struct OrderId(u64);
// fn process(user: UserId, order: OrderId) — compiler prevents swapsUserIdOrderIdstruct UserId(u64);
struct OrderId(u64);
// fn process(user: UserId, order: OrderId) — compiler prevents swapsstruct Connection<S> { socket: TcpStream, _state: PhantomData<S> }
struct Disconnected;
struct Connected;
impl Connection<Disconnected> {
fn connect(self) -> Result<Connection<Connected>> { ... }
}
impl Connection<Connected> {
fn send(&self, data: &[u8]) -> Result<()> { ... }
// send() is unavailable on Connection<Disconnected>
}struct Connection<S> { socket: TcpStream, _state: PhantomData<S> }
struct Disconnected;
struct Connected;
impl Connection<Disconnected> {
fn connect(self) -> Result<Connection<Connected>> { ... }
}
impl Connection<Connected> {
fn send(&self, data: &[u8]) -> Result<()> { ... }
// send() is unavailable on Connection<Disconnected>
}struct Matrix<const ROWS: usize, const COLS: usize> {
data: [[f64; COLS]; ROWS],
}
impl<const N: usize> Matrix<N, N> {
fn trace(&self) -> f64 { (0..N).map(|i| self.data[i][i]).sum() }
}struct Matrix<const ROWS: usize, const COLS: usize> {
data: [[f64; COLS]; ROWS],
}
impl<const N: usize> Matrix<N, N> {
fn trace(&self) -> f64 { (0..N).map(|i| self.data[i][i]).sum() }
}| Marker | Variance | Use for |
|---|---|---|
| Covariant | "Owns" a T conceptually |
| Contravariant | Consumes T (rare) |
| Invariant | Must be exact type |
| Invariant | Raw pointer semantics |
| 标记 | 变体类型 | 适用场景 |
|---|---|---|
| 协变 | 概念上“拥有”一个T |
| 逆变 | 消费T(罕见) |
| 不变 | 必须是精确类型 |
| 不变 | 裸指针语义 |
Is this a hot path (profiled, not guessed)?
NO → Write clear, idiomatic code. Don't optimize.
YES → Which bottleneck?
CPU-bound computation → rayon::par_iter() for data parallelism
Many small allocations → Arena allocator (bumpalo)
Iterator chain not vectorizing → Check for stateful dependencies,
use fold/try_fold, or restructure as plain slice iteration
Cache misses → #[repr(C)] + align, struct-of-arrays layout
Heap allocation → Box<[T]> instead of Vec<T> when size is fixed,
stack allocation for small types, SmallVec for usually-small vecsIs this a hot path (profiled, not guessed)?
NO → Write clear, idiomatic code. Don't optimize.
YES → Which bottleneck?
CPU-bound computation → rayon::par_iter() for data parallelism
Many small allocations → Arena allocator (bumpalo)
Iterator chain not vectorizing → Check for stateful dependencies,
use fold/try_fold, or restructure as plain slice iteration
Cache misses → #[repr(C)] + align, struct-of-arrays layout
Heap allocation → Box<[T]> instead of Vec<T> when size is fixed,
stack allocation for small types, SmallVec for usually-small vecsfilter().map().sum()references/performance.mdfilter().map().sum()references/performance.mdunsafe {}// SAFETY:unsafeasbytemuck::castfrom_raw_partstransmutetransmutebindgenunsafeunsafe {}unsafe// SAFETY:asbytemuck::castfrom_raw_partstransmutetransmutebindgenunsafeMutexGuard.await!Sendtokio::spawnRefCellborrow_mut()try_borrow_mut()MutexMutexcollect::<Vec<Result<T, E>>>()collect::<Result<Vec<T>, E>>()&String&str&String&str&strunwrap()?expect()#[must_use]Resultstd::sync::Mutextokio::sync::MutexString::fromString::with_capacity()Cow<str>select!clone()Box<dyn Error>thiserror.awaitMutexGuard!Sendtokio::spawnRefCellborrow_mut()try_borrow_mut()MutexMutexcollect::<Vec<Result<T, E>>>()collect::<Result<Vec<T>, E>>()&String&str&String&str&strunwrap()?expect()Result#[must_use]std::sync::Mutextokio::sync::MutexString::fromString::with_capacity()Cow<str>select!clone()Box<dyn Error>thiserror| File | When to read |
|---|---|
| Interior mutability, smart pointers, Cow, Pin, lifetime tricks |
| Trait objects, sealed traits, blanket impls, HRTB, variance |
| thiserror v2, anyhow, Result combinators, error design |
| Tokio runtime, cancellation, JoinSet, Send/Sync, select! |
| Zero-cost, SIMD, arena allocation, rayon, cache optimization |
| Unsafe superpowers, FFI with bindgen, transmute, raw pointers |
| Declarative macros, proc macros, derive macros, syn/quote |
| Newtype, typestate, PhantomData, const generics, builder |
| 文件 | 适用场景 |
|---|---|
| 内部可变性、智能指针、Cow、Pin、生命周期技巧 |
| Trait对象、密封Trait、通用实现、HRTB、变体 |
| thiserror v2、anyhow、Result组合子、错误设计 |
| Tokio运行时、取消、JoinSet、Send/Sync、select! |
| 零开销、SIMD、 arena 分配、rayon、缓存优化 |
| Unsafe能力、用bindgen做FFI、transmute、裸指针 |
| 声明宏、过程宏、派生宏、syn/quote |
| 新类型、类型状态、PhantomData、const泛型、构建器 |