在 Rust 中,Box<T>、Rc<T> 和 Arc<T> 这三种智能指针类型各自有何不同?请阐述它们在所有权、引用计数和线程安全方面的区别,并分别给出一个适合使用它们的典型场景。
考察说明
考查对 Rust 智能指针核心特性的理解,包括所有权、单线程与多线程引用计数的差异以及适用场景。
回答思路
- 【回答框架 1】Box<T> 用于堆上分配数据,拥有所有权且单一所有者,编译器在作用域结束时自动释放,无引用计数开销。适合编译期大小未知但运行时大小固定的数据,如递归类型,或用于转移大型数据所有权。
- 【回答框架 2】Rc<T> 是单线程引用计数指针,允许多个所有者共享不可变数据,通过 clone 增加计数,计数归零时清理数据。只适用于单线程场景,因为内部计数非线程安全。
- 【回答框架 3】Arc<T> 是原子引用计数指针,线程安全,适用于多线程共享数据,必须配合 Mutex、RwLock 等实现可变性,因为默认不支持可变借用。
- 【回答框架 4】选择依据:需要堆分配且唯一所有权用 Box;单线程多所有者用 Rc;多线程共享用 Arc,并注意线程安全限制。
- 【关键点 1】Box 提供单一所有权和堆分配,无运行时开销;Rc 单线程引用计数,Arc 线程安全引用计数。
- 【关键点 2】Rc 和 Arc 都只共享不可变数据,可变性需内部可变性或锁。
- 【关键点 3】Rc 不能跨线程使用,Arc 可以,但 Arc 性能略低。
- 【关键点 4】循环引用会导致内存泄漏,可用 Weak 打破。
- 【易错点 1】混淆 Rc 和 Arc 的线程安全性,误将 Rc 用于多线程。
- 【易错点 2】忽视循环引用导致的内存泄漏。
- 【易错点 3】认为 Arc 允许可变共享,实际需加锁。