注意到Rust中match
和if
在生存期方面的以下差异-假设我们有简单的结构:
struct Foo;
impl Foo {
is_valid(&self) -> bool { true }
}
和一个保存它的互斥锁
let foo = tokio::sync::Mutex::new(Foo);
对于以下match
,锁一直存在到match
构造结束:
match foo.lock().await.is_valid() {
_ => foo.lock().await.is_valid(), // Deadlock.
};
这不会完成,因为当第二行尝试获取锁时,锁仍然保持。但是使用if
将在计算bool后立即释放第一个锁:
if foo.lock().await.is_valid() {
foo.lock().await.is_valid(); // This is fine.
}
这段代码结束时锁被使用了两次。这是否意味着match
比if
挂起的引用更多?对此有何解释?
1条答案
按热度按时间0g0grzrc1#
我相信this issue会给予你你要找的信息。
简言之,Drop trait是在match语句中的所有内容都被解析之后触发的,这意味着在调用内部锁时,外部锁还没有被释放,对于if语句,Drop trait是在检查条件之后、调用条件块之前立即调用的。
有趣的是,
if let
表达式似乎也会发生这种情况。下面的代码也会死锁: