IB-Rust-智能指针&box
智能指针
智能指针概述
智能指针(Smart Pointers)是一类数据结构,不仅包含一个指针,还附带一些额外的元数据和功能。智能指针实现了 Deref 和 Drop 两个 trait,使得它们可以像指针一样解引用并在离开作用域时自动清理资源
智能指针作用
- 资源管理
- 自动管理资源的分配和释放,避免内存泄漏
- 所有权与借用
- Rust 的所有权系统通过智能指针来确保内存安全,避免数据竞争和悬垂指针
- 复杂数据结构
- 通过智能指针可以构建复杂的数据结构,如递归结构、共享数据等
BOX<T>
Box<T>将类型 T 的值分配在堆上,而不是栈上- 当 Box 被销毁时,堆上的数据也会被销毁
Box 的底层实现
- 底层原理
Box<T>实际上是一个智能指针,内部包含一个指向堆上分配内存的裸指针- 当
Box<T>被销毁时,其Droptrait 会被调用,释放堆上的内存
- 内存分配
- Rust 使用系统的全局分配器(如 malloc 和 free)来管理堆内存
- Box::new 分配内存,Drop 释放内存
- 安全性
- Rust 的所有权系统确保
Box<T>的内存安全。所有权转移时,堆内存的生命周期也会随之变化
- Rust 的所有权系统确保
Box 的使用场景
堆分配
Box 最常见的用途是将数据分配在堆上,而不是栈上。这在处理较大数据结构、或数据结构的大小在编译时不确定时尤为重要
1 | let b = Box::new(5); |
动态大小类型(DST)
Box 允许处理动态大小类型,如 str 和 [T]
1 | let s: Box<str> = "Hello, world!".into(); |
递归数据结构
递归数据结构需要指针类型引用自身,而 Box 提供了这一功能
1 | enum List { |
类型擦除
Box<dyn Trait> 用于类型擦除,允许在运行时决定类型
1 | trait Animal { |
dyn 关键字
dyn 关键字用于指定动态分发的类型,允许在运行时决定具体类型,可用于实现动态分发的 trait 对象
内存管理和性能优化
通过使用 Box,可以控制内存的分配和释放,从而优化性能和内存使用。例如,将大型数据结构放在堆上,而不是栈上,从而避免栈溢出
1 | let large_array = Box::new([0u8; 1_000_000]); |
Box 的优缺点
- 优点
- 提供堆内存分配,支持复杂数据结构
- 与 Rust 的所有权系统完美集成,确保内存安全
- 动态分配对象,实现类型擦除
- 缺点
- 需要堆内存分配和释放,可能带来性能开销
- 不适合需要频繁分配和释放的场景
Drop、Derefb 和 DerefMut
DropTraitDroptrait 定义了当一个值离开作用域时应该执行的操作- 例如:
Box<T>在超出作用域时会自动调用其 Drop trait,释放堆上的内存
DerefTraitDereftrait 定义了如何将一个类型转换为引用- 例如:
Box<T>实现了 Deref,所以可以通过 * 运算符解引用获取其内部数据
Drop Trait
Drop trait 用于自定义当值离开作用域时执行的代码,通常用于释放资源(例如内存、文件句柄、网络连接等)
定义和实现
Drop trait 定义了一个 drop 方法,当值被释放时,Rust 会自动调用这个方法
1 | pub trait Drop { |
1 | struct Resource { |
Deref Trait
Deref trait 用于重载解引用运算符(*),允许定义自定义指针类型的解引用行为
定义和实现
Deref trait 定义了一个 deref 方法,该方法返回指向目标类型的引用
1 | pub trait Deref { |
1 | use std::ops::Deref; |
DerefMut Trait
与 Deref 类似,DerefMut 用于重载可变解引用运算符(*),允许对自定义类型进行可变解引用
定义和实现
1 | pub trait DerefMut: Deref { |
1 | impl<T> DerefMut for MyBox<T> { |
课后作业
作业 1: 内存管理和性能优化
创建一个大型数组并将其分配到堆上,然后测量和比较分配在堆和栈上的性能差异。
创建一个包含 1_000_000 个元素的数组,分别将其分配在堆和栈上。使用 std::time::Instant 来测量分配和访问时间。
1 | use std::time::Instant; |
作业2:实现一个简单的文件系统模拟
目标
实现一个简单的文件系统模拟,其中包含文件和文件夹的概念。文件夹可以包含文件和其他文件夹。使用 Box 来管理内存,并实现对文件系统的基本操作(如创建文件、创建文件夹、列出文件和文件夹)。作业要求
- 定义
FileSystemtrait 和 Node 枚举FileSystemtrait 包含create_file、create_folder和list_contents方法。Node枚举包含File和Folder变体。
- 实现
FolderNode结构体FolderNode实现FileSystemtrait,包含name和contents字段。- 使用
Box管理contents中的子节点。
- 实现文件系统的基本操作
create_file方法在文件夹中创建文件。create_folder方法在文件夹中创建子文件夹。list_contents方法列出文件夹的所有内容。
- 测试文件系统的操作
- 创建根文件夹并添加文件和文件夹。
- 创建子文件夹并添加文件。
- 列出文件夹的内容并输出文件系统结构。
- 定义
提示
使用Box来管理Folder中的子节点。
使用递归方法来遍历和列出文件和文件夹的内容。
考虑使用Vec来存储文件夹的子节点。
1 | trait FileSystem { |
- Title: IB-Rust-智能指针&box
- Author: Gabrielle
- Created at : 2025-06-04 13:18:38
- Updated at : 2025-06-05 23:37:26
- Link: https://zoella-w.github.io/2025/06/04/74-IB-Rust-智能指针&box/
- License: This work is licensed under CC BY-NC-SA 4.0.