Skip to content

什么是智能指针

概念名称: 智能指针是拥有数据并附加元数据的类型,自动管理资源生命周期。

语法结构:
┌──────────────────────────────────────┐
│  智能指针 = 指针 + 元数据 + 能力     │
│                                       │
│  实现两个核心 Trait:                  │
│  Deref  → 像引用一样访问 (*ptr)      │
│  Drop   → 离开作用域自动清理          │
│                                       │
│  常见类型:                            │
│  Box<T>      → 堆上分配                │
│  Rc<T>       → 引用计数(单线程)     │
│  Arc<T>      → 引用计数(多线程)     │
│  RefCell<T>  → 内部可变性             │
└──────────────────────────────────────┘

最简示例

rust
fn main() {
    let b = Box::new(5);
    println!("b = {}", *b);  // Deref 解引用
}  // Drop 自动释放堆内存
▶ Run

智能指针 vs 普通引用

┌─────────────────────────────────────────────────────┐
│              智能指针是什么                          │
├─────────────────────────────────────────────────────┤
│                                                     │
│  与普通指针的区别:                                  │
│  ┌─────────────┬─────────────┬─────────────┐       │
│  │             │ 普通引用    │ 智能指针    │       │
│  ├─────────────┼─────────────┼─────────────┤       │
│  │ 所有权      │ 借用        │ 拥有        │       │
│  │ 元数据      │ 无          │ 有          │       │
│  │ 运行时开销  │ 无          │ 少量        │       │
│  │ 自动清理    │ 编译器管理  │ 自动 Drop   │       │
│  └─────────────┴─────────────┴─────────────┘       │
│                                                     │
│  常见智能指针:                                      │
│  • Box<T>      - 堆上分配                           │
│  • Rc<T>       - 引用计数(单线程)                 │
│  • Arc<T>      - 引用计数(多线程)                 │
│  • RefCell<T>  - 内部可变性                         │
│                                                     │
└─────────────────────────────────────────────────────┘

为什么用它?

rust
// 没有智能指针:数据只能在栈上或手动管理
// let data = ???;  // 大对象放栈上会溢出

// 有智能指针:自动管理堆内存
let data = Box::new(vec![0; 1_000_000]);  // 堆上分配 1MB
println!("大小:{}", data.len());
// 离开作用域自动释放
▶ Run

智能指针的共同特点

rust
// 1. 实现 Deref trait(像引用一样使用)
// 2. 实现 Drop trait(自动清理)

// Deref 示例
impl<T> Deref for Box<T> {
    type Target = T;
    fn deref(&self) -> &T {
        // 返回内部数据的引用
        unimplemented!()
    }
}

// Drop 示例
impl<T> Drop for Box<T> {
    fn drop(&mut self) {
        // 自动释放堆上内存
    }
}
▶ Run

关键代码说明:

代码含义为什么这样写
Box::new(5)堆上分配将数据从栈移到堆上
*b解引用通过 Deref trait 访问内部值
Deref trait解引用重载让智能指针像引用一样使用
Drop trait析构函数离开作用域时自动清理资源