Rust的match表达式是否支持类似C++ if的初始化器以解决死锁?
Rust Match 支持类似C++带初始化器的if语法吗?
Rust的match本身没有C++那种带初始化器的语法,但有两种简单的替代方案,既能实现你想要的逻辑,还能解决代码里的死锁问题。
死锁原因分析
你代码里的问题在于:match ar.lock().unwrap().is_ok会临时获取锁,读取is_ok后立刻释放锁;而false分支里又再次调用ar.lock().unwrap(),如果此时有其他线程持有锁,就会触发死锁。就算单线程场景,也可能因为时序问题导致意外,正确的做法是只获取一次锁,复用同一个锁守卫(MutexGuard)。
解决方案1:提前绑定变量
直接在match前获取锁并绑定到变量,锁守卫会在整个match块执行完毕后才释放,分支里可以直接复用变量:
use std::sync::{Arc, Mutex}; struct A { id: u32, is_ok: bool, } impl A { fn new(id: u32) -> Self { Self { id, is_ok: false, } } } fn main() { let ar = Arc::new(Mutex::new(A::new(1))); let a = ar.lock().unwrap(); match a.is_ok { true => {}, false => println!("{}", a.id), }; }
解决方案2:块表达式包裹
如果不想让变量污染外部作用域,可以用块表达式把初始化和match包起来,变量仅在块内有效:
use std::sync::{Arc, Mutex}; struct A { id: u32, is_ok: bool, } impl A { fn new(id: u32) -> Self { Self { id, is_ok: false, } } } fn main() { let ar = Arc::new(Mutex::new(A::new(1))); { let a = ar.lock().unwrap(); match a.is_ok { true => {}, false => println!("{}", a.id), }; } }
这两种方式都和C++带初始化器的if逻辑等价,既能避免重复加锁导致的死锁,又能实现“先初始化变量再匹配”的需求。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

