Rust 中的 Drop Trait
2019-08-10 16:08 rust
Drop Trait
先看代码:
#[derive(Default)]
struct Point {
pub x: i32,
pub y: i32,
}
#[derive(Default)]
struct Rectangle {
pub p1: Point,
pub p2: Point,
}
impl Drop for Point {
fn drop(&mut self) {
println!("Point {} {} ::drop()", self.x, self.y);
}
}
impl Drop for Rectangle {
fn drop(&mut self) {
println!("Rectangle::drop()");
}
}
fn main() {
let _p = Point::default();
let _r = Rectangle {
p1: Point { x: 1, y: 2 },
p2: Point { x: 3, y: 4 },
};
}
打印的结果是:
Rectangle::drop()
Point 1 2 ::drop()
Point 3 4 ::drop()
Point 0 0 ::drop()
可以发现 Drop Trait
的几个特性:
Drop::drop()
方法是被隐式调用的.- 先调用了
Rectangle::drop()
, 之后调用了其内部属性的Point::drop()
. Rectangle
内部性性的drop()
方法是基于声明的先后顺序调用的. 上面才会先打印Point 1 2 ::drop()
, 再打印Point 3 4 ::drop()
.- 先声明的变量后被
drop
. 上面的试验, 先 drop 了Rectangle _r
, 之后再 drop 了Point _p
.
另外还有几个特点:
Drop::drop()
是不能手动调用的.Drop
trait 只能用于结构体 (struct), 不能用于 primative type.
mem::drop
尽管不能手动调用 Drop::drop()
方法来 destruct
一个结构体, 但我们可以调用
std::mem::drop()
函数, 这个函数的实现也是非常简单的.
#[inline]
fn drop(_x: T) { }
它获取了传入参数的所有权, 然后什么都不做, 等该函数运行完之后, 该变量 _x
的值
的生命周期已完成, 它就要被释放掉.
我们来修改一下上面的测试代码:
fn main() {
let p = Point::default();
let _r = Rectangle {
p1: Point { x: 1, y: 2 },
p2: Point { x: 3, y: 4 },
};
std::mem::drop(p);
}
这次的打印结果是:
Point 0 0 ::drop()
Rectangle::drop()
Point 1 2 ::drop()
Point 3 4 ::drop()
Point p
优先被 drop
了, 因为 std::mem::drop(p);
这条调用完结之后, Point p
的生命周期就完结了. 之后, 在 main()
函数结束时, 自动调用了 Rectangle _r
的 drop()
方法.
关于 mem::drop()
有一点要注意的是, 它只能用来 drop
没有实现 Copy trait
的变量,
像 rust 里的原始数据类型, usize/u8/u16/u32/u64/u128/... 这些都是实现了 Copy trait
的,
mem::drop()
来 drop 它们时, 是没有效果的. 比如下面的代码, 变量 x
在传入 drop()
函数时, 它的值是被复制了一份的, 所以并不能 drop
变量 x
本身.
let x = 42;
std::mem::drop(x);