Rust 的 Drop 顺序:谁先走,谁后走
先看一段不会打印出 done 的代码:
1use std::sync::Mutex;
2
3fn main() {
4 let counter = Mutex::new(0);[ CATEGORY ]
rust 分类下共有 3 篇编程实战文章,涵盖常见问题排查、代码示例与实践经验。
先看一段不会打印出 done 的代码:
1use std::sync::Mutex;
2
3fn main() {
4 let counter = Mutex::new(0);Rust 的所有权规则在编译期解决大部分问题:一个值只有一个所有者,借用要么多个不可变,要么一个可变。但只要写稍微复杂一点的数据结构——树、图、双向链表、观察者列表——就会撞上同一个问题:我需要多个地方共享同一份数据,而且还要修改它。
标准库给出的答案是 Rc<T> 加 RefCell<T>。这个组合确实能用,但它把编译期的检查搬到了运行时,代价是 panic、引用计数开销,以及一种 Rust 里罕见的 bug:内存泄漏。这篇文章从一个真实场景出发,把这几个坑逐个拆开。
Box<T> 是独占所有权,赋值即移动。如果两个父节点要共享同一个子节点,Box 就无能为力了。Rc<T>(Reference Counting)通过引用计数实现多所有者:每次 clone 只是把计数加一,数据本身不动。
写 Rust 时,很多人第一次卡住的地方不是所有权,而是 ?。代码看起来只是把错误往上抛,编译器却报出 the trait bound ... From<...> is not implemented;改成 fn main() -> Result<(), Box<dyn Error>> 后能编译了,运行时又只打印一行看不懂的 Debug。要解决这些问题,需要先弄清 ? 到底做了什么。
? 展开后只做两件事下面这行代码:
1let port = read_port()?;