在 Rust 编程语言中,Arc 和 Rc 是两种非常重要的智能指针,它们都用于实现引用计数(Reference Counting),从而允许多个所有者共享同一份数据。但它们的使用场景截然不同:一个用于多线程环境,另一个仅限于单线程。
本文将用通俗易懂的方式,带你彻底搞懂 Rust Arc 与 Rc 的区别,并附上清晰的代码示例,即使是编程新手也能轻松掌握!
Rc<T>(Reference Counted)是 Rust 标准库提供的一个智能指针,用于在单线程环境中实现多个所有者共享同一数据。每当创建一个新的 Rc 指向某数据时,引用计数加一;当某个 Rc 被丢弃时,引用计数减一。当计数归零,数据被自动释放。
注意:Rc 不是线程安全的,不能跨线程使用。
use std::rc::Rc;fn main() { let data = Rc::new(42); println!("初始引用计数: {}", Rc::strong_count(&data)); { let data_clone1 = Rc::clone(&data); let data_clone2 = Rc::clone(&data); println!("克隆后引用计数: {}", Rc::strong_count(&data)); // data_clone1 和 data_clone2 在这里离开作用域 } println!("作用域结束后引用计数: {}", Rc::strong_count(&data));} 运行结果:
初始引用计数: 1克隆后引用计数: 3作用域结束后引用计数: 1
Arc<T>(Atomically Reference Counted)是 Rc 的线程安全版本。它通过原子操作(Atomic Operations)来保证在多线程环境下引用计数的增减是安全的。
因此,当你需要在多个线程之间共享不可变数据时,必须使用 Arc,而不是 Rc。
use std::sync::Arc;use std::thread;fn main() { let data = Arc::new(vec![1, 2, 3]); let mut handles = vec![]; for i in 0..3 { let data_clone = Arc::clone(&data); let handle = thread::spawn(move || { println!("线程 {} 读取数据: {:?}", i, data_clone); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); }} 这段代码展示了如何在三个线程中安全地共享同一个 Vec。如果这里使用 Rc,编译器会报错,因为 Rc 不满足 Send trait,无法跨线程传递。
| 特性 | Rc<T> | Arc<T> |
|---|---|---|
| 全称 | Reference Counted | Atomically Reference Counted |
| 线程安全 | ❌ 否 | ✅ 是 |
| 性能开销 | 低(无原子操作) | 较高(需原子操作) |
| 适用场景 | 单线程共享数据 | 多线程共享不可变数据 |
Rc —— 它更轻量、更快。Arc。Rc 会导致编译错误。掌握 Rust Arc 与 Rc 的区别是理解 Rust 内存管理和并发模型的关键一步。无论是构建高性能单线程应用,还是编写安全的多线程程序,合理使用这两种智能指针都能让你的代码更安全、更高效。
希望这篇教程能帮助你彻底搞懂 Rust 智能指针的核心概念!如果你觉得有用,欢迎分享给其他 Rust 学习者。
关键词回顾:Rust Arc与Rc区别、Rust智能指针、Arc多线程共享、Rc单线程引用计数。
本文由主机测评网于2025-12-08发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025124856.html