掌握Box、Rc、Arc、RefCell等智能指针,理解所有权与借用的运行时扩展。
fn main() {
// 在堆上分配
let b = Box::new(5);
println!("b = {}", b);
// 递归类型必须用Box
enum List {
Cons(i32, Box<List>),
Nil,
}
use List::*;
let list = Cons(1, Box::new(Cons(2, Box::new(Nil))));
// 动态大小类型
fn process(s: Box<dyn std::fmt::Display>) {
println!("{}", s);
}
process(Box::new(42));
process(Box::new("hello"));
}
✅ 编译验证通过
use std::ops::Deref;
struct MyBox<T>(T>;
impl<T> MyBox<T> {
fn new(x: T) -> Self { MyBox(x) }
}
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn hello(name: &str) { println!("Hello, {}!", name); }
fn main() {
let m = MyBox::new(String::from("Rust"));
hello(&m); // Deref强制转换: &MyBox<String> → &String → &str
}
✅ 编译验证通过
struct CustomPointer {
data: String,
}
impl Drop for CustomPointer {
fn drop(&mut self) {
println!("释放: {}", self.data);
}
}
fn main() {
let c = CustomPointer { data: String::from("资源A") };
println!("使用中...");
// c.drop(); // ❌ 不允许显式调用
drop(c); // ✅ std::mem::drop
println!("已释放");
}
✅ 编译验证通过
use std::rc::Rc;
fn main() {
let a = Rc::new(String::from("共享数据"));
let b = Rc::clone(&a); // 增加引用计数,不复制数据!
let c = Rc::clone(&a);
println!("引用计数: {}", Rc::strong_count(&a));
println!("值: {}", *a);
// Rc只能用于单线程!
}
✅ 编译验证通过
use std::cell::RefCell;
fn main() {
let data = RefCell::new(vec![1, 2, 3]);
// 借用检查移到运行时
data.borrow_mut().push(4); // 可变借用
println!("{:?}", data.borrow()); // 不可变借用
// ⚠️ 运行时借用冲突会panic!
// let ref1 = data.borrow();
// let ref2 = data.borrow_mut(); // 💥 panic!
}
✅ 编译验证通过
use std::sync::Arc;
use std::thread;
fn main() {
let data = Arc::new(vec![1, 2, 3]);
let mut handles = vec![];
for _ in 0..3 {
let data_clone = Arc::clone(&data);
handles.push(thread::spawn(move || {
println!("线程读取: {:?}", data_clone);
}));
}
for h in handles { h.join().unwrap(); }
}
✅ 编译验证通过
| 类型 | 所有权 | 线程安全 | 可变性 | 开销 |
|---|---|---|---|---|
Box<T> | 唯一 | ✅ | 编译期 | 无 |
Rc<T> | 共享 | ❌ | 编译期 | 引用计数 |
Arc<T> | 共享 | ✅ | 编译期 | 原子计数 |
RefCell<T> | 唯一 | ❌ | 运行时 | 运行时检查 |
Mutex<T> | 共享 | ✅ | 运行时 | 锁 |
用Rc+RefCell实现双向链表。
用Rc实现有向无环图。
实现一个简单的引用计数智能指针。
掌握智能指针——突破编译期限制的钥匙
以下资源帮助你深入学习本课主题:
本课涉及的核心概念,确保你理解每一个:
| 术语 | 说明 |
|---|---|
| 所有权 | Rust内存管理的核心机制,每个值有唯一所有者 |
| 借用 | 通过引用访问数据,不获取所有权 |
| 生命周期 | 引用有效的范围,编译期分析工具 |
| trait | Rust的接口/抽象机制,类似其他语言的接口 |
| 泛型 | 参数化类型,零成本抽象 |
| 模式匹配 | 强大的数据解构和分支机制 |
| 零成本抽象 | 高层抽象不引入运行时开销 |
| fearless concurrency | 编译器保证线程安全 |
Q: Rust学习曲线真的很陡吗?
A: 前期确实需要适应所有权和借用检查器,但一旦理解了,这些概念会让你的代码更可靠。大多数人2-4周就能上手。
Q: Rust适合什么项目?
A: 系统编程、Web服务、CLI工具、嵌入式、WASM、网络服务、数据库等。基本上需要性能和安全的地方都适合。
Q: 遇到编译错误怎么办?
A: Rust编译器的错误信息非常友好!仔细阅读,通常会指出问题所在和修复建议。也可以用cargo clippy获取更多提示。