You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中match为何比if持有引用的时间更长?

Rust中match与if在锁持有生命周期上的差异解析

问题场景

首先定义一个简单结构体:

struct Foo;

impl Foo {
    fn is_valid(&self) -> bool { true }
}

再用Tokio的互斥锁包裹该结构体:

let foo = tokio::sync::Mutex::new(Foo);

用match导致死锁

match foo.lock().await.is_valid() {
    _ => foo.lock().await.is_valid(), // 死锁
};

这段代码无法执行完成,因为第二次尝试获取锁时,第一个锁仍未释放。

用if可正常执行

if foo.lock().await.is_valid() {
    foo.lock().await.is_valid(); // 正常执行
}

这段代码能正常完成,锁会被成功获取两次。

背后的原因

这确实是因为match持有临时值(此处为互斥锁的MutexGuard)的时间比if更长,核心源于Rust对临时值销毁时机的规则差异:

  • if表达式的临时值销毁时机:if的条件表达式求值完成后,只要其结果没有被后续代码借用,临时值就会立即销毁。这里foo.lock().await返回的MutexGuard仅用来调用is_valid()得到布尔值,之后Guard不再被引用,因此会立刻被释放,锁也随之释放。

  • match表达式的临时值销毁时机:match后的 scrutinee(即匹配的目标表达式)会被整个match块持有,直到整个match执行完毕才会销毁。Rust这样设计是为了保证在所有匹配分支中,scrutinee的值始终有效(比如分支中若用到了scrutinee的引用,不会出现悬垂引用)。即便你这里只用到了is_valid()的返回值,Rust仍会保留整个scrutinee(包括MutexGuard)直到match结束,导致第一个锁持续被持有,第二次获取锁时就触发了死锁。

简单总结:if条件的临时值在判断完成后立即销毁,而match的目标表达式临时值会存活整个match块的生命周期。

内容的提问来源于stack exchange,提问作者itarato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 01:55:18