前言
在平时的开发中,我们可能需要利用析构函数来做一些收尾工作。在 Rust 中我们可以利用 Drop trait 来实现。本篇文章将会用最短的篇幅覆盖 Drop 的主要知识点。
impl Drop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
extern crate hello_rust;
struct DT {
id: i32,
}
impl Drop for DT {
fn drop(&mut self) {
println!("drop call!");
}
}
fn main() {
let dt = DT { id: 1 };
println!("{:?}", dt.id);
}
|
主动析构
一般我们定义的局部变量生命周期都是当前语句块, 析构顺序“先进后出”。不过 Rust 中我们也可以手动使用 drop
函数提前结束它的生命周期。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
extern crate hello_rust;
struct DT {
id: i32,
}
impl Drop for DT {
fn drop(&mut self) {
println!("drop call!");
}
}
fn main() {
let dt = DT { id: 1 };
drop(dt); // 这里不能直接调用 dt.drop()
println!("end!");
}
|
drop
函数体内啥也没有,单纯就是把所有权拿到然后函数结束才好让析构函数执行。也因为它利用了 Rust 默认的移动语义,它和 Copy trait 是有冲突的。所以在 Rust 中同一个类型是不允许同时实现 Copy 和 Drop 的。
析构函数的调用是在编译阶段就确定好的,而我们可以在代码的不同执行路径中主动析构从而影响析构函数的调用顺序,那这不是矛盾吗?
1
2
3
4
5
|
match condition {
Some(1) => drop(var1)
Some(2) => drop(var2)
_ => {}
}
|
其实这里我们可以理解为 Rust 会用一个布尔值来判断,如果执行到最后还没有析构过才会调用析构函数。如果在执行期间已经析构了,是不会重复调用的。