rust-systems-programming

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Rust Systems Programming

Rust系统编程

A comprehensive skill for building high-performance, memory-safe systems software using Rust. This skill covers ownership, borrowing, concurrency, async programming, unsafe code, FFI, and performance optimization for systems-level development.
这是一份使用Rust构建高性能、内存安全系统软件的全面指南,涵盖系统级开发中的所有权、借用、并发、异步编程、不安全代码、FFI(外部函数接口)及性能优化等内容。

When to Use This Skill

何时使用本指南

Use this skill when:
  • Building systems software requiring memory safety without garbage collection
  • Developing high-performance applications with zero-cost abstractions
  • Writing concurrent or parallel programs with data race prevention
  • Creating async/await applications for I/O-bound workloads (web servers, databases)
  • Working with low-level code, FFI, or hardware interfaces
  • Replacing C/C++ code with safer alternatives
  • Building command-line tools, network services, or embedded systems
  • Optimizing performance-critical sections of applications
  • Creating libraries that guarantee memory safety at compile time
  • Developing WebAssembly modules for near-native performance
在以下场景中使用本指南:
  • 构建无需垃圾回收且要求内存安全的系统软件
  • 开发具备零成本抽象的高性能应用
  • 编写可防止数据竞争的并发或并行程序
  • 为I/O密集型工作负载(Web服务器、数据库)创建async/await应用
  • 处理底层代码、FFI或硬件接口
  • 使用更安全的替代方案替换C/C++代码
  • 构建命令行工具、网络服务或嵌入式系统
  • 优化应用中性能关键的代码段
  • 创建在编译期保证内存安全的库
  • 开发具备接近原生性能的WebAssembly模块

Core Concepts

核心概念

The Ownership Model

所有权模型

Rust's ownership system is the foundation of its memory safety guarantees:
Ownership Rules:
  1. Each value in Rust has exactly one owner
  2. When the owner goes out of scope, the value is dropped
  3. Ownership can be transferred (moved) to new owners
Move Semantics:
rust
struct MyStruct { s: u32 }

fn main() {
    let mut x = MyStruct{ s: 5u32 };
    let y = x;  // Ownership moved from x to y
    // x.s = 6;  // ERROR: x is no longer valid
    // println!("{}", x.s);  // ERROR: cannot use x after move
}
When a type doesn't implement
Copy
, assignment moves ownership rather than copying. This prevents double-free errors and use-after-move bugs at compile time.
For Copy Types:
rust
let x = 5;  // i32 implements Copy
let y = x;  // x is copied, not moved
println!("{}", x);  // OK: x is still valid
Rust的所有权系统是其内存安全保障的基础:
所有权规则:
  1. Rust中的每个值恰好有一个所有者
  2. 当所有者离开作用域时,对应的值会被销毁
  3. 所有权可以转移(移动)给新的所有者
移动语义:
rust
struct MyStruct { s: u32 }

fn main() {
    let mut x = MyStruct{ s: 5u32 };
    let y = x;  // 所有权从x移动到y
    // x.s = 6;  // 错误:x不再有效
    // println!("{}", x.s);  // 错误:移动后无法使用x
}
当类型未实现
Copy
时,赋值操作会转移所有权而非复制。这在编译期就防止了双重释放错误和移动后使用的bug。
对于实现Copy的类型:
rust
let x = 5;  // i32实现了Copy
let y = x;  // x被复制,而非移动
println!("{}", x);  // 正常:x仍然有效

Borrowing and References

借用与引用

Borrowing allows temporary access to data without taking ownership:
Immutable Borrowing:
rust
fn main() {
    let s1 = String::from("hello");

    let len = calculate_length(&s1);  // Borrow s1 immutably

    println!("The length of '{}' is {}.", s1, len);  // s1 still valid
}

fn calculate_length(s: &String) -> usize {
    s.len()  // Can read but not modify
}
Mutable Borrowing:
Rust enforces exclusive mutable access to prevent data races:
rust
fn main() {
    let mut value = 3;
    let borrow = &mut value;  // Mutable borrow
    *borrow += 1;
    println!("{}", borrow);  // 4

    // value is accessible again after borrow ends
}
Borrowing Rules:
  • You can have either one mutable reference OR any number of immutable references
  • References must always be valid (no dangling pointers)
  • Mutable and immutable borrows cannot coexist
Common Borrowing Error:
rust
fn main() {
    let mut value = 3;
    // Create a mutable borrow of `value`.
    let borrow = &mut value;
    let _sum = value + 1; // ERROR: cannot use `value` because
                          //        it was mutably borrowed
    println!("{}", borrow);
}
借用允许临时访问数据而无需获取所有权:
不可变借用:
rust
fn main() {
    let s1 = String::from("hello");

    let len = calculate_length(&s1);  // 不可变借用s1

    println!("'{}'的长度是{}", s1, len);  // s1仍然有效
}

fn calculate_length(s: &String) -> usize {
    s.len()  // 仅可读取,不可修改
}
可变借用:
Rust强制要求独占可变访问以防止数据竞争:
rust
fn main() {
    let mut value = 3;
    let borrow = &mut value;  // 可变借用
    *borrow += 1;
    println!("{}", borrow);  // 4

    // 借用结束后,value可再次被访问
}
借用规则:
  • 你可以拥有一个可变引用,或者任意数量的不可变引用,但二者不能同时存在
  • 引用必须始终有效(无悬空指针)
  • 可变借用与不可变借用不能共存
常见借用错误:
rust
fn main() {
    let mut value = 3;
    // 创建`value`的可变借用
    let borrow = &mut value;
    let _sum = value + 1; // 错误:无法使用`value`,因为它已被可变借用
    println!("{}", borrow);
}

Lifetimes

生命周期

Lifetimes ensure references are always valid:
rust
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}
The
'a
lifetime parameter tells the compiler that the returned reference will be valid as long as both input references are valid.
生命周期确保引用始终有效:
rust
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}
'a
生命周期参数告知编译器,返回的引用的有效期与两个输入引用的有效期一致。

Ownership Patterns for Sharing

用于共享的所有权模式

Rc (Reference Counted) for Single-threaded Shared Ownership:
rust
use std::cell::RefCell;
use std::rc::Rc;

struct MyStruct { s: u32 }

fn main() {
    let mut x = Rc::new(RefCell::new(MyStruct{ s: 5u32 }));
    let y = x.clone();  // Increment reference count
    x.borrow_mut().s = 6;  // Interior mutability via RefCell
    println!("{}", x.borrow().s);
}
Rc<T>
provides shared ownership with reference counting.
RefCell<T>
enables interior mutability, enforcing borrow rules at runtime rather than compile time.
Arc (Atomic Reference Counted) for Thread-safe Sharing:
rust
use std::sync::Arc;
use std::thread;

struct FancyNum {
    num: u8,
}

fn main() {
    let fancy_ref1 = Arc::new(FancyNum { num: 5 });
    let fancy_ref2 = fancy_ref1.clone();

    let x = thread::spawn(move || {
        // `fancy_ref1` can be moved and has a `'static` lifetime
        println!("child thread: {}", fancy_ref1.num);
    });

    x.join().expect("child thread should finish");
    println!("main thread: {}", fancy_ref2.num);
}
Arc<T>
is the thread-safe version of
Rc<T>
, using atomic operations for reference counting.
Rc(引用计数):单线程下的共享所有权
rust
use std::cell::RefCell;
use std::rc::Rc;

struct MyStruct { s: u32 }

fn main() {
    let mut x = Rc::new(RefCell::new(MyStruct{ s: 5u32 }));
    let y = x.clone();  // 增加引用计数
    x.borrow_mut().s = 6;  // 通过RefCell实现内部可变性
    println!("{}", x.borrow().s);
}
Rc<T>
提供基于引用计数的共享所有权。
RefCell<T>
启用内部可变性,在运行时而非编译期强制执行借用规则。
Arc(原子引用计数):线程安全的共享
rust
use std::sync::Arc;
use std::thread;

struct FancyNum {
    num: u8,
}

fn main() {
    let fancy_ref1 = Arc::new(FancyNum { num: 5 });
    let fancy_ref2 = fancy_ref1.clone();

    let x = thread::spawn(move || {
        // `fancy_ref1`可被移动,且具有`'static`生命周期
        println!("child thread: {}", fancy_ref1.num);
    });

    x.join().expect("child thread should finish");
    println!("main thread: {}", fancy_ref2.num);
}
Arc<T>
Rc<T>
的线程安全版本,使用原子操作进行引用计数。

Box for Heap Allocation

Box:堆内存分配

rust
Box<T>
Box<T>
is an owning pointer that allocates
T
on the heap. Useful for:
  • Recursive types with known size
  • Large values that should not be copied on the stack
  • Trait objects with dynamic dispatch
rust
Box<T>
Box<T>
是一种拥有型指针,会在堆上分配
T
。适用于:
  • 大小已知的递归类型
  • 不应在栈上复制的大型值
  • 具备动态分发的 trait 对象

Concurrency Patterns

并发模式

Threads and Message Passing

线程与消息传递

Rust prevents data races at compile time through its ownership system:
rust
use std::thread;
use std::sync::mpsc;

fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        tx.send("Hello from thread").unwrap();
    });

    let message = rx.recv().unwrap();
    println!("{}", message);
}
Rust通过其所有权系统在编译期防止数据竞争:
rust
use std::thread;
use std::sync::mpsc;

fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        tx.send("Hello from thread").unwrap();
    });

    let message = rx.recv().unwrap();
    println!("{}", message);
}

Shared State with Mutex

使用Mutex实现共享状态

rust
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Result: {}", *counter.lock().unwrap());
}
Key Concurrency Types:
  • Mutex<T>
    : Mutual exclusion lock for shared mutable state
  • RwLock<T>
    : Reader-writer lock allowing multiple readers or one writer
  • Arc<T>
    : Atomic reference counting for thread-safe sharing
  • mpsc
    : Multi-producer, single-consumer channels
rust
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Result: {}", *counter.lock().unwrap());
}
核心并发类型:
  • Mutex<T>
    :用于共享可变状态的互斥锁
  • RwLock<T>
    :允许多个读取者或一个写入者的读写锁
  • Arc<T>
    :用于线程安全共享的原子引用计数
  • mpsc
    :多生产者、单消费者通道

Data Race Prevention

数据竞争预防

ThreadSanitizer Example:
rust
static mut A: usize = 0;

fn main() {
    let t = std::thread::spawn(|| {
        unsafe { A += 1 };
    });
    unsafe { A += 1 };

    t.join().unwrap();
}
This code has a data race. ThreadSanitizer (enabled with
RUSTFLAGS=-Zsanitizer=thread
) detects concurrent access to static mutable data:
WARNING: ThreadSanitizer: data race (pid=10574)
  Read of size 8 at 0x5632dfe3d030 by thread T1:
  Previous write of size 8 at 0x5632dfe3d030 by main thread:
ThreadSanitizer示例:
rust
static mut A: usize = 0;

fn main() {
    let t = std::thread::spawn(|| {
        unsafe { A += 1 };
    });
    unsafe { A += 1 };

    t.join().unwrap();
}
这段代码存在数据竞争。ThreadSanitizer(通过
RUSTFLAGS=-Zsanitizer=thread
启用)可检测到对静态可变数据的并发访问:
WARNING: ThreadSanitizer: data race (pid=10574)
  Read of size 8 at 0x5632dfe3d030 by thread T1:
  Previous write of size 8 at 0x5632dfe3d030 by main thread:

Async Programming

异步编程

Async/Await Basics

Async/Await基础

Async programming in Rust allows concurrent I/O without blocking threads:
rust
async fn foo(n: usize) {
    if n > 0 {
        Box::pin(foo(n - 1)).await;
    }
}
Recursive async functions require
Box::pin()
to give the future a known size.
Rust中的异步编程允许在不阻塞线程的情况下处理并发I/O:
rust
async fn foo(n: usize) {
    if n > 0 {
        Box::pin(foo(n - 1)).await;
    }
}
递归异步函数需要
Box::pin()
来为future提供已知大小。

Async Closures

异步闭包

Async Closure with Move Semantics:
rust
fn force_fnonce<T: async FnOnce()>(t: T) -> T { t }

let x = String::new();
let c = force_fnonce(async move || {
    println!("{x}");
});
When constrained to
AsyncFnOnce
, the closure captures by move to ensure proper ownership.
Async Closure Borrowing:
rust
let x = &1i32; // Lifetime '1
let c = async move || {
    println!("{:?}", *x);
    // Even though the closure moves x, we're only capturing *x,
    // so the inner coroutine can reborrow the data for its original lifetime.
};
Mutable Borrowing in Async Closures:
rust
let mut x = 1i32;
let c = async || {
    x = 1;
    // The parent borrows `x` mutably.
    // When we call `c()`, we implicitly autoref for `AsyncFnMut::async_call_mut`.
    // The inner coroutine captures with the lifetime of the coroutine-closure.
};
具备移动语义的异步闭包:
rust
fn force_fnonce<T: async FnOnce()>(t: T) -> T { t }

let x = String::new();
let c = force_fnonce(async move || {
    println!("{x}");
});
当约束为
AsyncFnOnce
时,闭包会通过移动捕获变量以确保正确的所有权。
异步闭包的借用:
rust
let x = &1i32; // 生命周期'1
let c = async move || {
    println!("{:?}", *x);
    // 尽管闭包移动了x,但我们仅捕获了*x,因此内部协程可以为其原始生命周期重新借用数据。
};
异步闭包中的可变借用:
rust
let mut x = 1i32;
let c = async || {
    x = 1;
    // 父级可变借用`x`
    // 当我们调用`c()`时,会隐式自动引用以调用`AsyncFnMut::async_call_mut`
    // 内部协程以协程闭包的生命周期捕获数据。
};

Common Async Errors

常见异步错误

E0373: Async block capturing short-lived variable:
rust
use std::future::Future;

async fn f() {
    let v = vec![1, 2, 3i32];
    spawn(async { //~ ERROR E0373
        println!("{:?}", v)  // v might go out of scope before async block runs
    });
}

fn spawn<F: Future + Send + 'static>(future: F) {
    unimplemented!()
}
Solution: Move the variable into the async block:
rust
spawn(async move {
    println!("{:?}", v)
})
E0373:异步块捕获短生命周期变量:
rust
use std::future::Future;

async fn f() {
    let v = vec![1, 2, 3i32];
    spawn(async { //~ 错误E0373
        println!("{:?}", v)  // v可能在异步块运行前就离开作用域
    });
}

fn spawn<F: Future + Send + 'static>(future: F) {
    unimplemented!()
}
解决方案:将变量移动到异步块中:
rust
spawn(async move {
    println!("{:?}", v)
})

Unsafe Code and FFI

不安全代码与FFI

When to Use Unsafe

何时使用Unsafe

Rust's
unsafe
keyword allows operations that the compiler cannot verify:
  1. Dereferencing raw pointers
  2. Calling unsafe functions or methods
  3. Accessing or modifying mutable static variables
  4. Implementing unsafe traits
  5. Accessing fields of unions
Unsafe Dereference Example:
rust
macro_rules! unsafe_deref {
    () => {
        *(&() as *const ())
    };
}
Rust的
unsafe
关键字允许编译器无法验证的操作:
  1. 解引用原始指针
  2. 调用不安全函数或方法
  3. 访问或修改可变静态变量
  4. 实现不安全trait
  5. 访问联合体的字段
不安全解引用示例:
rust
macro_rules! unsafe_deref {
    () => {
        *(&() as *const ())
    };
}

Memory Safety with Unsafe

不安全代码的内存安全

Unsafe Sync Implementation:
rust
use std::cell::Cell;

struct NotThreadSafe<T> {
    value: Cell<T>,
}

unsafe impl<T> Sync for NotThreadSafe<T> {}

static A: NotThreadSafe<usize> = NotThreadSafe { value : Cell::new(1) };
static B: &'static NotThreadSafe<usize> = &A; // ok!
This is
unsafe
because you must manually ensure thread safety.
Cell
is not
Sync
by default, so this implementation requires careful reasoning.
不安全Sync实现:
rust
use std::cell::Cell;

struct NotThreadSafe<T> {
    value: Cell<T>,
}

unsafe impl<T> Sync for NotThreadSafe<T> {}

static A: NotThreadSafe<usize> = NotThreadSafe { value : Cell::new(1) };
static B: &'static NotThreadSafe<usize> = &A; // 正常!
这是
unsafe
的,因为你必须手动确保线程安全。
Cell
默认不实现
Sync
,因此该实现需要仔细的逻辑验证。

FFI (Foreign Function Interface)

FFI(外部函数接口)

Calling C Functions from Rust:
rust
use std::mem;

#[link(name = "foo")]
extern "C" {
    fn do_twice(f: unsafe extern "C" fn(i32) -> i32, arg: i32) -> i32;
}

unsafe extern "C" fn add_one(x: i32) -> i32 {
    x + 1
}

unsafe extern "C" fn add_two(x: i64) -> i64 {
    x + 2
}

fn main() {
    let answer = unsafe { do_twice(add_one, 5) };
    println!("The answer is: {}", answer);

    // Type-mismatched call (unsafe):
    println!("With CFI enabled, you should not see the next answer");
    let f: unsafe extern "C" fn(i32) -> i32 = unsafe {
        mem::transmute::<*const u8, unsafe extern "C" fn(i32) -> i32>(add_two as *const u8)
    };
    let next_answer = unsafe { do_twice(f, 5) };
    println!("The next answer is: {}", next_answer);
}
Control Flow Integrity (CFI): With CFI enabled, the type-mismatched transmute causes program termination, preventing control flow hijacking.
Inline Assembly for System Calls:
rust
static UNMAP_BASE: usize;
const MEM_RELEASE: usize;
static VirtualFree: usize;
const OffPtr: usize;
const OffFn: usize;

core::arch::asm!("
    push {free_type}
    push {free_size}
    push {base}

    mov eax, fs:[30h]
    mov eax, [eax+8h]
    add eax, {off_fn}
    mov [eax-{off_fn}+{off_ptr}], eax

    push eax

    jmp {virtual_free}
    ",
    off_ptr = const OffPtr,
    off_fn  = const OffFn,

    free_size = const 0,
    free_type = const MEM_RELEASE,

    virtual_free = sym VirtualFree,

    base = sym UNMAP_BASE,
    options(noreturn),
);
This demonstrates direct system calls using inline assembly for Windows memory deallocation.
从Rust调用C函数:
rust
use std::mem;

#[link(name = "foo")]
extern "C" {
    fn do_twice(f: unsafe extern "C" fn(i32) -> i32, arg: i32) -> i32;
}

unsafe extern "C" fn add_one(x: i32) -> i32 {
    x + 1
}

unsafe extern "C" fn add_two(x: i64) -> i64 {
    x + 2
}

fn main() {
    let answer = unsafe { do_twice(add_one, 5) };
    println!("The answer is: {}", answer);

    // 类型不匹配的调用(不安全):
    println!("With CFI enabled, you should not see the next answer");
    let f: unsafe extern "C" fn(i32) -> i32 = unsafe {
        mem::transmute::<*const u8, unsafe extern "C" fn(i32) -> i32>(add_two as *const u8)
    };
    let next_answer = unsafe { do_twice(f, 5) };
    println!("The next answer is: {}", next_answer);
}
控制流完整性(CFI): 启用CFI后,类型不匹配的transmute会导致程序终止,防止控制流劫持。
用于系统调用的内联汇编:
rust
static UNMAP_BASE: usize;
const MEM_RELEASE: usize;
static VirtualFree: usize;
const OffPtr: usize;
const OffFn: usize;

core::arch::asm!("
    push {free_type}
    push {free_size}
    push {base}

    mov eax, fs:[30h]
    mov eax, [eax+8h]
    add eax, {off_fn}
    mov [eax-{off_fn}+{off_ptr}], eax

    push eax

    jmp {virtual_free}
    ",
    off_ptr = const OffPtr,
    off_fn  = const OffFn,

    free_size = const 0,
    free_type = const MEM_RELEASE,

    virtual_free = sym VirtualFree,

    base = sym UNMAP_BASE,
    options(noreturn),
);
这展示了使用内联汇编直接调用Windows内存释放的系统调用。

Error Handling

错误处理

Result and Option Types

Result与Option类型

Rust uses
Result<T, E>
and
Option<T>
for error handling:
rust
fn divide(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        Err("Division by zero".to_string())
    } else {
        Ok(a / b)
    }
}

fn main() {
    match divide(10, 2) {
        Ok(result) => println!("Result: {}", result),
        Err(e) => println!("Error: {}", e),
    }
}
Rust使用
Result<T, E>
Option<T>
进行错误处理:
rust
fn divide(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        Err("Division by zero".to_string())
    } else {
        Ok(a / b)
    }
}

fn main() {
    match divide(10, 2) {
        Ok(result) => println!("Result: {}", result),
        Err(e) => println!("Error: {}", e),
    }
}

The ? Operator

?运算符

rust
fn process_file(path: &str) -> Result<String, std::io::Error> {
    let content = std::fs::read_to_string(path)?;
    Ok(content.to_uppercase())
}
The
?
operator propagates errors up the call stack, similar to exceptions but explicit in the type signature.
rust
fn process_file(path: &str) -> Result<String, std::io::Error> {
    let content = std::fs::read_to_string(path)?;
    Ok(content.to_uppercase())
}
?
运算符会将错误向上传播到调用栈,类似于异常但在类型签名中显式声明。

Custom Error Types

自定义错误类型

rust
use std::fmt;

#[derive(Debug)]
enum AppError {
    IoError(std::io::Error),
    ParseError(std::num::ParseIntError),
    Custom(String),
}

impl fmt::Display for AppError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            AppError::IoError(e) => write!(f, "IO error: {}", e),
            AppError::ParseError(e) => write!(f, "Parse error: {}", e),
            AppError::Custom(msg) => write!(f, "Error: {}", msg),
        }
    }
}

impl std::error::Error for AppError {}
rust
use std::fmt;

#[derive(Debug)]
enum AppError {
    IoError(std::io::Error),
    ParseError(std::num::ParseIntError),
    Custom(String),
}

impl fmt::Display for AppError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            AppError::IoError(e) => write!(f, "IO error: {}", e),
            AppError::ParseError(e) => write!(f, "Parse error: {}", e),
            AppError::Custom(msg) => write!(f, "Error: {}", msg),
        }
    }
}

impl std::error::Error for AppError {}

Memory Safety and Sanitizers

内存安全与Sanitizers

AddressSanitizer

AddressSanitizer

Detecting Stack Buffer Overflow:
rust
fn main() {
    let xs = [0, 1, 2, 3];
    let _y = unsafe { *xs.as_ptr().offset(4) };
}
Build with AddressSanitizer:
shell
$ export RUSTFLAGS=-Zsanitizer=address RUSTDOCFLAGS=-Zsanitizer=address
$ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
Output:
==37882==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe400e6250
READ of size 4 at 0x7ffe400e6250 thread T0
    #0 0x5609a841fb1f in example::main::h628ffc6626ed85b2 /.../src/main.rs:3:23

Address 0x7ffe400e6250 is located in stack of thread T0 at offset 48 in frame
  This frame has 1 object(s):
    [32, 48) 'xs' (line 2) <== Memory access at offset 48 overflows this variable
Detecting Heap Buffer Overflow:
rust
fn main() {
    let xs = vec![0, 1, 2, 3];
    let _y = unsafe { *xs.as_ptr().offset(4) };
}
Detecting Use-After-Scope:
rust
static mut P: *mut usize = std::ptr::null_mut();

fn main() {
    unsafe {
        {
            let mut x = 0;
            P = &mut x;
        }
        std::ptr::write_volatile(P, 123);  // P points to dropped variable
    }
}
AddressSanitizer output:
==39249==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffc7ed3e1a0
WRITE of size 8 at 0x7ffc7ed3e1a0 thread T0
检测栈缓冲区溢出:
rust
fn main() {
    let xs = [0, 1, 2, 3];
    let _y = unsafe { *xs.as_ptr().offset(4) };
}
使用AddressSanitizer构建:
shell
$ export RUSTFLAGS=-Zsanitizer=address RUSTDOCFLAGS=-Zsanitizer=address
$ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
输出:
==37882==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe400e6250
READ of size 4 at 0x7ffe400e6250 thread T0
    #0 0x5609a841fb1f in example::main::h628ffc6626ed85b2 /.../src/main.rs:3:23

Address 0x7ffe400e6250 is located in stack of thread T0 at offset 48 in frame
  This frame has 1 object(s):
    [32, 48) 'xs' (line 2) <== Memory access at offset 48 overflows this variable
检测堆缓冲区溢出:
rust
fn main() {
    let xs = vec![0, 1, 2, 3];
    let _y = unsafe { *xs.as_ptr().offset(4) };
}
检测作用域后使用:
rust
static mut P: *mut usize = std::ptr::null_mut();

fn main() {
    unsafe {
        {
            let mut x = 0;
            P = &mut x;
        }
        std::ptr::write_volatile(P, 123);  // P指向已销毁的变量
    }
}
AddressSanitizer输出:
==39249==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffc7ed3e1a0
WRITE of size 8 at 0x7ffc7ed3e1a0 thread T0

Performance Optimization

性能优化

Zero-Cost Abstractions

零成本抽象

Rust provides high-level abstractions without runtime overhead:
rust
// Iterator chains are optimized to simple loops
let sum: i32 = (1..100)
    .filter(|x| x % 2 == 0)
    .map(|x| x * x)
    .sum();
The compiler optimizes this to a tight loop equivalent to manual iteration.
Rust提供高级抽象且无运行时开销:
rust
// 迭代器链会被优化为简单循环
let sum: i32 = (1..100)
    .filter(|x| x % 2 == 0)
    .map(|x| x * x)
    .sum();
编译器会将其优化为与手动迭代等效的紧凑循环。

Inlining and Monomorphization

内联与单态化

Generic functions are monomorphized (specialized) for each concrete type:
rust
#[inline]
fn add<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
    a + b
}

let x = add(5, 3);      // Specialized for i32
let y = add(5.0, 3.0);  // Specialized for f64
泛型函数会针对每个具体类型进行单态化(特化):
rust
#[inline]
fn add<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
    a + b
}

let x = add(5, 3);      // 针对i32特化
let y = add(5.0, 3.0);  // 针对f64特化

Smart Pointer Overhead

智能指针开销

Different smart pointers have different costs:
  • Box<T>
    : Single heap allocation, no overhead
  • Rc<T>
    : Reference counting, small overhead per clone/drop
  • Arc<T>
    : Atomic reference counting, higher overhead for thread safety
  • Mutex<T>
    : Lock acquisition overhead
  • RefCell<T>
    : Runtime borrow checking overhead
不同智能指针的开销不同:
  • Box<T>
    :单次堆分配,无额外开销
  • Rc<T>
    :引用计数,每次克隆/销毁有少量开销
  • Arc<T>
    :原子引用计数,线程安全带来更高开销
  • Mutex<T>
    :锁获取开销
  • RefCell<T>
    :运行时借用检查开销

Avoiding Allocations

避免不必要的分配

rust
// Bad: Allocates a new String
fn greet_bad(name: &str) -> String {
    format!("Hello, {}", name)
}

// Good: Returns a reference, no allocation
fn greet_good(name: &str) -> impl std::fmt::Display + '_ {
    format_args!("Hello, {}", name)
}
rust
// 不佳:分配新的String
fn greet_bad(name: &str) -> String {
    format!("Hello, {}", name)
}

// 良好:返回引用,无分配
fn greet_good(name: &str) -> impl std::fmt::Display + '_ {
    format_args!("Hello, {}", name)
}

Common Patterns and Idioms

常见模式与惯用写法

Builder Pattern

构建器模式

rust
struct Config {
    host: String,
    port: u16,
    timeout: u64,
}

impl Config {
    fn builder() -> ConfigBuilder {
        ConfigBuilder::default()
    }
}

#[derive(Default)]
struct ConfigBuilder {
    host: Option<String>,
    port: Option<u16>,
    timeout: Option<u64>,
}

impl ConfigBuilder {
    fn host(mut self, host: impl Into<String>) -> Self {
        self.host = Some(host.into());
        self
    }

    fn port(mut self, port: u16) -> Self {
        self.port = Some(port);
        self
    }

    fn build(self) -> Config {
        Config {
            host: self.host.unwrap_or_else(|| "localhost".to_string()),
            port: self.port.unwrap_or(8080),
            timeout: self.timeout.unwrap_or(30),
        }
    }
}
rust
struct Config {
    host: String,
    port: u16,
    timeout: u64,
}

impl Config {
    fn builder() -> ConfigBuilder {
        ConfigBuilder::default()
    }
}

#[derive(Default)]
struct ConfigBuilder {
    host: Option<String>,
    port: Option<u16>,
    timeout: Option<u64>,
}

impl ConfigBuilder {
    fn host(mut self, host: impl Into<String>) -> Self {
        self.host = Some(host.into());
        self
    }

    fn port(mut self, port: u16) -> Self {
        self.port = Some(port);
        self
    }

    fn build(self) -> Config {
        Config {
            host: self.host.unwrap_or_else(|| "localhost".to_string()),
            port: self.port.unwrap_or(8080),
            timeout: self.timeout.unwrap_or(30),
        }
    }
}

Newtype Pattern

Newtype模式

rust
struct UserId(u64);
struct PostId(u64);

fn get_user(id: UserId) -> User { /* ... */ }

// This won't compile: type safety!
// get_user(PostId(42));
rust
struct UserId(u64);
struct PostId(u64);

fn get_user(id: UserId) -> User { /* ... */ }

// 这无法编译:类型安全保障!
// get_user(PostId(42));

RAII (Resource Acquisition Is Initialization)

RAII(资源获取即初始化)

rust
struct FileGuard {
    file: std::fs::File,
}

impl FileGuard {
    fn new(path: &str) -> std::io::Result<Self> {
        Ok(FileGuard {
            file: std::fs::File::create(path)?,
        })
    }
}

impl Drop for FileGuard {
    fn drop(&mut self) {
        println!("File closed automatically");
    }
}
rust
struct FileGuard {
    file: std::fs::File,
}

impl FileGuard {
    fn new(path: &str) -> std::io::Result<Self> {
        Ok(FileGuard {
            file: std::fs::File::create(path)?,
        })
    }
}

impl Drop for FileGuard {
    fn drop(&mut self) {
        println!("File closed automatically");
    }
}

Closure Patterns and Errors

闭包模式与错误

E0500: Closure Borrowing Conflict

E0500:闭包借用冲突

Problem:
rust
fn you_know_nothing(jon_snow: &mut i32) {
    let nights_watch = &jon_snow;
    let starks = || {
        *jon_snow = 3; // error: closure requires unique access to `jon_snow`
                       //        but it is already borrowed
    };
    println!("{}", nights_watch);
}
Solution:
rust
fn you_know_nothing(jon_snow: &mut i32) {
    let nights_watch = &jon_snow;
    println!("{}", nights_watch);  // Use the borrow first
    // Borrow ends here (non-lexical lifetimes)
    let starks = || {
        *jon_snow = 3;  // Now OK
    };
}
问题:
rust
fn you_know_nothing(jon_snow: &mut i32) {
    let nights_watch = &jon_snow;
    let starks = || {
        *jon_snow = 3; // 错误:闭包需要对`jon_snow`的独占访问,但它已被借用
    };
    println!("{}", nights_watch);
}
解决方案:
rust
fn you_know_nothing(jon_snow: &mut i32) {
    let nights_watch = &jon_snow;
    println!("{}", nights_watch);  // 先使用借用
    // 借用在此结束(非词法生命周期)
    let starks = || {
        *jon_snow = 3;  // 现在可以正常使用
    };
}

E0502: Mutable and Immutable Borrows

E0502:可变与不可变借用共存

Problem:
rust
fn bar(x: &mut i32) {}
fn foo(a: &mut i32) {
    let y = &a;
    bar(a);  // Error: cannot borrow as mutable while borrowed as immutable
    println!("{}", y);
}
Solution:
rust
fn bar(x: &mut i32) {}
fn foo(a: &mut i32) {
    bar(a);  // Mutable borrow first
    let y = &a; // Immutable borrow after mutable borrow ends
    println!("{}", y);
}
问题:
rust
fn bar(x: &mut i32) {}
fn foo(a: &mut i32) {
    let y = &a;
    bar(a);  // 错误:在不可变借用期间无法进行可变借用
    println!("{}", y);
}
解决方案:
rust
fn bar(x: &mut i32) {}
fn foo(a: &mut i32) {
    bar(a);  // 先进行可变借用
    let y = &a; // 可变借用结束后再进行不可变借用
    println!("{}", y);
}

E0505: Move of Borrowed Value

E0505:移动已借用的值

Problem:
rust
struct Value {}

fn borrow(val: &Value) {}
fn eat(val: Value) {}

fn main() {
    let x = Value{};
    let _ref_to_val: &Value = &x;
    eat(x);  // Error: cannot move x while borrowed
    borrow(_ref_to_val);
}
问题:
rust
struct Value {}

fn borrow(val: &Value) {}
fn eat(val: Value) {}

fn main() {
    let x = Value{};
    let _ref_to_val: &Value = &x;
    eat(x);  // 错误:值已被借用,无法移动
    borrow(_ref_to_val);
}

E0524: Concurrent Mutable Borrows in Closures

E0524:闭包中的并发可变借用

Problem:
rust
fn set(x: &mut isize) {
    *x += 4;
}

fn dragoooon(x: &mut isize) {
    let mut c1 = || set(x);
    let mut c2 = || set(x); // error: two closures trying to borrow mutably
    c2();
    c1();
}
Solution 1: Sequential Execution (Non-Lexical Lifetimes)
rust
fn set(x: &mut isize) {
    *x += 4;
}

fn dragoooon(x: &mut isize) {
    {
        let mut c1 = || set(&mut *x);
        c1();
    } // `c1` has been dropped here so we're free to use `x` again!
    let mut c2 = || set(&mut *x);
    c2();
}
Solution 2: Rc + RefCell for Shared Mutable Access
rust
use std::rc::Rc;
use std::cell::RefCell;

fn set(x: &mut isize) {
    *x += 4;
}

fn dragoooon(x: &mut isize) {
    let x = Rc::new(RefCell::new(x));
    let y = Rc::clone(&x);
    let mut c1 = || { let mut x2 = x.borrow_mut(); set(&mut x2); };
    let mut c2 = || { let mut x2 = y.borrow_mut(); set(&mut x2); };

    c2();
    c1();
}
问题:
rust
fn set(x: &mut isize) {
    *x += 4;
}

fn dragoooon(x: &mut isize) {
    let mut c1 = || set(x);
    let mut c2 = || set(x); // 错误:两个闭包尝试可变借用同一变量
    c2();
    c1();
}
解决方案1:顺序执行(非词法生命周期)
rust
fn set(x: &mut isize) {
    *x += 4;
}

fn dragoooon(x: &mut isize) {
    {
        let mut c1 = || set(&mut *x);
        c1();
    } // `c1`已被销毁,现在可以再次使用`x`!
    let mut c2 = || set(&mut *x);
    c2();
}
解决方案2:使用Rc + RefCell实现共享可变访问
rust
use std::rc::Rc;
use std::cell::RefCell;

fn set(x: &mut isize) {
    *x += 4;
}

fn dragoooon(x: &mut isize) {
    let x = Rc::new(RefCell::new(x));
    let y = Rc::clone(&x);
    let mut c1 = || { let mut x2 = x.borrow_mut(); set(&mut x2); };
    let mut c2 = || { let mut x2 = y.borrow_mut(); set(&mut x2); };

    c2();
    c1();
}

E0507: Moving Borrowed Content

E0507:移动已借用的内容

Problem:
rust
use std::cell::RefCell;

struct TheDarkKnight;

impl TheDarkKnight {
    fn nothing_is_true(self) {}
}

fn main() {
    let x = RefCell::new(TheDarkKnight);
    x.borrow().nothing_is_true(); // Error: cannot move out of borrowed content
}
Solution 1: Take a Reference
rust
impl TheDarkKnight {
    fn nothing_is_true(&self) {}  // Change to &self
}

fn main() {
    let x = RefCell::new(TheDarkKnight);
    x.borrow().nothing_is_true(); // OK
}
Solution 2: Reclaim Ownership
rust
fn main() {
    let x = RefCell::new(TheDarkKnight);
    let x = x.into_inner(); // Reclaim ownership
    x.nothing_is_true(); // OK
}
问题:
rust
use std::cell::RefCell;

struct TheDarkKnight;

impl TheDarkKnight {
    fn nothing_is_true(self) {}
}

fn main() {
    let x = RefCell::new(TheDarkKnight);
    x.borrow().nothing_is_true(); // 错误:无法从借用的内容中移动
}
解决方案1:使用引用
rust
impl TheDarkKnight {
    fn nothing_is_true(&self) {}  // 修改为&self
}

fn main() {
    let x = RefCell::new(TheDarkKnight);
    x.borrow().nothing_is_true(); // 正常
}
解决方案2:重新获取所有权
rust
fn main() {
    let x = RefCell::new(TheDarkKnight);
    let x = x.into_inner(); // 重新获取所有权
    x.nothing_is_true(); // 正常
}

Production Patterns

生产环境模式

Structured Logging

结构化日志

rust
use tracing::{info, warn, error, instrument};

#[instrument]
async fn process_request(id: u64) -> Result<(), Error> {
    info!(request_id = id, "Processing request");

    match do_work(id).await {
        Ok(_) => {
            info!("Request completed successfully");
            Ok(())
        }
        Err(e) => {
            error!(error = ?e, "Request failed");
            Err(e)
        }
    }
}
rust
use tracing::{info, warn, error, instrument};

#[instrument]
async fn process_request(id: u64) -> Result<(), Error> {
    info!(request_id = id, "Processing request");

    match do_work(id).await {
        Ok(_) => {
            info!("Request completed successfully");
            Ok(())
        }
        Err(e) => {
            error!(error = ?e, "Request failed");
            Err(e)
        }
    }
}

Configuration Management

配置管理

rust
use serde::Deserialize;

#[derive(Deserialize)]
struct AppConfig {
    database_url: String,
    server_port: u16,
    log_level: String,
}

fn load_config() -> Result<AppConfig, config::ConfigError> {
    config::Config::builder()
        .add_source(config::File::with_name("config"))
        .add_source(config::Environment::with_prefix("APP"))
        .build()?
        .try_deserialize()
}
rust
use serde::Deserialize;

#[derive(Deserialize)]
struct AppConfig {
    database_url: String,
    server_port: u16,
    log_level: String,
}

fn load_config() -> Result<AppConfig, config::ConfigError> {
    config::Config::builder()
        .add_source(config::File::with_name("config"))
        .add_source(config::Environment::with_prefix("APP"))
        .build()?
        .try_deserialize()
}

Graceful Shutdown

优雅关闭

rust
use tokio::signal;

async fn shutdown_signal() {
    let ctrl_c = async {
        signal::ctrl_c()
            .await
            .expect("failed to install Ctrl+C handler");
    };

    #[cfg(unix)]
    let terminate = async {
        signal::unix::signal(signal::unix::SignalKind::terminate())
            .expect("failed to install signal handler")
            .recv()
            .await;
    };

    #[cfg(not(unix))]
    let terminate = std::future::pending::<()>();

    tokio::select! {
        _ = ctrl_c => {},
        _ = terminate => {},
    }

    println!("Shutdown signal received, starting graceful shutdown");
}
rust
use tokio::signal;

async fn shutdown_signal() {
    let ctrl_c = async {
        signal::ctrl_c()
            .await
            .expect("failed to install Ctrl+C handler");
    };

    #[cfg(unix)]
    let terminate = async {
        signal::unix::signal(signal::unix::SignalKind::terminate())
            .expect("failed to install signal handler")
            .recv()
            .await;
    };

    #[cfg(not(unix))]
    let terminate = std::future::pending::<()>();

    tokio::select! {
        _ = ctrl_c => {},
        _ = terminate => {},
    }

    println!("Shutdown signal received, starting graceful shutdown");
}

Connection Pooling

连接池

rust
use deadpool_postgres::{Config, Pool, Runtime};
use tokio_postgres::NoTls;

async fn create_pool() -> Pool {
    let mut cfg = Config::new();
    cfg.host = Some("localhost".to_string());
    cfg.dbname = Some("mydb".to_string());

    cfg.create_pool(Some(Runtime::Tokio1), NoTls)
        .expect("Failed to create pool")
}

async fn query_user(pool: &Pool, id: i64) -> Result<User, Error> {
    let client = pool.get().await?;
    let row = client
        .query_one("SELECT * FROM users WHERE id = $1", &[&id])
        .await?;
    Ok(User::from_row(row))
}
rust
use deadpool_postgres::{Config, Pool, Runtime};
use tokio_postgres::NoTls;

async fn create_pool() -> Pool {
    let mut cfg = Config::new();
    cfg.host = Some("localhost".to_string());
    cfg.dbname = Some("mydb".to_string());

    cfg.create_pool(Some(Runtime::Tokio1), NoTls)
        .expect("Failed to create pool")
}

async fn query_user(pool: &Pool, id: i64) -> Result<User, Error> {
    let client = pool.get().await?;
    let row = client
        .query_one("SELECT * FROM users WHERE id = $1", &[&id])
        .await?;
    Ok(User::from_row(row))
}

Best Practices

最佳实践

API Design

API设计

  1. Use References by Default: Accept
    &T
    instead of
    T
    unless you need ownership
  2. Return Owned Types: Return
    String
    instead of
    &str
    for simpler APIs
  3. Implement Standard Traits:
    Debug
    ,
    Clone
    ,
    PartialEq
    ,
    Send
    ,
    Sync
  4. Use
    Into<T>
    for Flexibility
    :
    fn set_name(&mut self, name: impl Into<String>)
  5. Leverage the Type System: Use newtypes, enums, and Result for correctness
  1. 默认使用引用:接受
    &T
    而非
    T
    ,除非你需要所有权
  2. 返回拥有型类型:返回
    String
    而非
    &str
    以简化API
  3. 实现标准trait
    Debug
    Clone
    PartialEq
    Send
    Sync
  4. 使用
    Into<T>
    提升灵活性
    fn set_name(&mut self, name: impl Into<String>)
  5. 利用类型系统:使用newtype、枚举和Result保障正确性

Testing Patterns

测试模式

rust
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_addition() {
        assert_eq!(add(2, 2), 4);
    }

    #[test]
    #[should_panic(expected = "division by zero")]
    fn test_divide_by_zero() {
        divide(10, 0);
    }

    #[tokio::test]
    async fn test_async_function() {
        let result = fetch_data().await;
        assert!(result.is_ok());
    }
}
rust
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_addition() {
        assert_eq!(add(2, 2), 4);
    }

    #[test]
    #[should_panic(expected = "division by zero")]
    fn test_divide_by_zero() {
        divide(10, 0);
    }

    #[tokio::test]
    async fn test_async_function() {
        let result = fetch_data().await;
        assert!(result.is_ok());
    }
}

Documentation

文档

rust
/// Calculates the sum of two numbers.
///
/// # Examples
///
/// ```
/// let result = add(2, 2);
/// assert_eq!(result, 4);
/// ```
///
/// # Panics
///
/// This function will panic if the result overflows.
pub fn add(a: i32, b: i32) -> i32 {
    a.checked_add(b).expect("overflow in add")
}
rust
/// 计算两个数字的和。
///
/// # 示例
///
/// ```
/// let result = add(2, 2);
/// assert_eq!(result, 4);
/// ```
///
/// # 恐慌情况
///
/// 如果结果溢出,该函数会触发恐慌。
pub fn add(a: i32, b: i32) -> i32 {
    a.checked_add(b).expect("overflow in add")
}

Dependency Management

依赖管理

toml
[dependencies]
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
tracing = "0.1"

[dev-dependencies]
criterion = "0.5"

[profile.release]
lto = true
codegen-units = 1
toml
[dependencies]
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
tracing = "0.1"

[dev-dependencies]
criterion = "0.5"

[profile.release]
lto = true
codegen-units = 1

Troubleshooting

故障排查

Common Borrow Checker Issues

常见借用检查器问题

Issue: "Cannot borrow as mutable because it is also borrowed as immutable" Solution: Ensure mutable and immutable borrows don't overlap in scope
Issue: "Cannot move out of borrowed content" Solution: Clone the value, take a reference, or use
Rc<RefCell<T>>
Issue: "Lifetime issues with references" Solution: Add explicit lifetime annotations or restructure code to avoid complex lifetimes
问题:“无法可变借用,因为它同时被不可变借用” 解决方案:确保可变借用与不可变借用的作用域不重叠
问题:“无法从已借用的内容中移动” 解决方案:克隆值、使用引用,或使用
Rc<RefCell<T>>
问题:“引用的生命周期问题” 解决方案:添加显式生命周期注解,或重构代码以避免复杂的生命周期

Performance Issues

性能问题

Issue: Slow compilation times Solution: Use incremental compilation, reduce generic instantiations, use
cargo check
Issue: Runtime performance slower than expected Solution: Profile with
perf
, enable LTO, check for unnecessary allocations/clones
Issue: High memory usage Solution: Use references instead of clones, consider streaming data, profile with Valgrind
问题:编译速度慢 解决方案:使用增量编译、减少泛型实例化、使用
cargo check
问题:运行时性能低于预期 解决方案:使用
perf
进行性能分析、启用LTO、检查不必要的分配/克隆
问题:内存占用高 解决方案:使用引用而非克隆、考虑流式处理数据、使用Valgrind进行分析

Concurrency Issues

并发问题

Issue: Deadlocks with multiple mutexes Solution: Always acquire locks in the same order, use
try_lock
with timeout
Issue: Data races in unsafe code Solution: Run with ThreadSanitizer, carefully review unsafe blocks
Issue: Async tasks not making progress Solution: Check for blocking operations in async code, use
spawn_blocking
for CPU-bound work
问题:多个Mutex导致死锁 解决方案:始终按相同顺序获取锁、使用带超时的
try_lock
问题:不安全代码中的数据竞争 解决方案:使用ThreadSanitizer运行、仔细审查不安全代码块
问题:异步任务无进展 解决方案:检查异步代码中的阻塞操作、对CPU密集型工作使用
spawn_blocking

Quick Reference

快速参考

Smart Pointer Cheat Sheet

智能指针速查表

Box<T>     - Heap allocation, single owner
Rc<T>      - Reference counted, single-threaded
Arc<T>     - Atomic reference counted, thread-safe
Mutex<T>   - Mutual exclusion lock
RwLock<T>  - Reader-writer lock
RefCell<T> - Runtime borrow checking
Cell<T>    - Interior mutability for Copy types
Box<T>     - 堆内存分配,单一所有者
Rc<T>      - 引用计数,单线程
Arc<T>     - 原子引用计数,线程安全
Mutex<T>   - 互斥锁
RwLock<T>  - 读写锁
RefCell<T> - 运行时借用检查
Cell<T>    - Copy类型的内部可变性

Common Trait Implementations

常见Trait实现

rust
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct MyStruct {
    field: String,
}

impl Default for MyStruct {
    fn default() -> Self {
        Self {
            field: String::new(),
        }
    }
}

impl std::fmt::Display for MyStruct {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "MyStruct({})", self.field)
    }
}
rust
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct MyStruct {
    field: String,
}

impl Default for MyStruct {
    fn default() -> Self {
        Self {
            field: String::new(),
        }
    }
}

impl std::fmt::Display for MyStruct {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "MyStruct({})", self.field)
    }
}

Async Runtime Comparison

异步运行时对比

Tokio:    Full-featured, most popular, excellent ecosystem
async-std: Mirrors std library API, simpler for beginners
smol:     Lightweight, minimal dependencies
Tokio:    功能完整,最受欢迎,生态丰富
async-std: 镜像标准库API,对初学者更友好
smol:     轻量级,依赖极少

Resources

资源


Skill Version: 1.0.0 Last Updated: October 2025 Skill Category: Systems Programming, Performance, Memory Safety Context7 Integration: Rust documentation and error code examples

技能版本:1.0.0 最后更新:2025年10月 技能分类:系统编程、性能优化、内存安全 Context7集成:Rust文档及错误代码示例