#[stable(feature = "rust1", since = "1.0.0")]
#[unsafe_destructor]
impl<T> Drop for JoinHandle<T> {
fn drop(&mut self) {
if !self.0.joined {
unsafe { imp::detach(self.0.native) }
}
}
}
例如,这里使用Drop::drop来分离线程。 在Vec::vec这样的集合中:
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Drop for Vec<T> {
fn drop(&mut self) {
// This is (and should always remain) a no-op if the fields are
// zeroed (when moving out, because of #[unsafe_no_drop_flag]).
if self.cap != 0 && self.cap != mem::POST_DROP_USIZE {
unsafe {
for x in &*self {
ptr::read(x);
}
dealloc(*self.ptr, self.cap)
}
}
}
}
2条答案
按热度按时间92dk7w1h1#
让我们看看
std::mem::drop
是如何实现的:没错这是一个空函数!这是因为它利用了move语义来获取其参数的所有权。如果
T
实现了Drop
,编译器会自动在函数的末尾插入一个对Drop::drop(_x)
的调用。这会发生在所有通过value接收的参数上(也就是说,实际上,* 所有 * 参数,但删除引用并不会删除referent)。现在考虑一下如果
Drop::drop
通过值获取参数会发生什么:编译器会尝试调用Drop::drop
中的参数Drop::drop
-这会导致堆栈溢出!当然,你可以调用参数mem::drop
,它也会尝试递归调用Drop::drop
。cbwuti442#
实际上,
Drop::drop
没有必要取得该值的所有权。在Rust中,所有权在语言级别自动处理,因此编译器确保正确实现所有权语义;因此,当
Foo { a: int, b: String }
超出范围时,编译器将通过自动删除其内部字段来删除Foo
。因此,
Drop::drop
没有必要删除字段!实际上,* 在
Foo
上调用 *Drop::drop
之后,编译器将自己mem::drop
不同的字段(也可能在定义它的字段上调用Drop::drop
,例如这里的b: String
)。Drop::drop
是什么意思它用于在编译器将要做的事情之上实现 * 额外的 * 逻辑;以
JoinHandle
为例:例如,这里使用
Drop::drop
来分离线程。在
Vec::vec
这样的集合中:在这里,由于原始内存是以编译器不透明的方式操作的,因此该实现负责:
1.删除vector中的每个元素
1.释放内存