`if let` 不 运行 析构函数 if 中间值

`if let` does not run destructor if intermediary value

考虑两段语义相同的代码:

let x = Mutex::new(0);
if *x.lock().unwrap() == 0 {
    *x.lock().unwrap() = 1;
}
let x = Mutex::new(0);
if let 0 = *x.lock().unwrap() {
    *x.lock().unwrap() = 1;
}

第一个 运行 符合预期,而第二个死锁。为什么 guard 析构函数被 if 运行 而不是 if let?在哪里可以找到有关此行为的文档?

答案可以在docs.rust-lang.org. Specifically refer to if let文章中找到,文章中说:

An if let expression is equivalent to a match expression as follows:

if let PATS = EXPR { /* body */ } else { /*else */ }

is equivalent to

match EXPR { PATS => { /* body */ }, _ => { /* else */ } }

前往match文章后,据说

A match behaves differently depending on whether or not the scrutinee expression is a place expression or value expression.

If the scrutinee expression is a value expression, it is first evaluated into a temporary location, and the resulting value is sequentially compared to the patterns in the arms until a match is found. The first arm with a matching pattern is chosen as the branch target of the match, any variables bound by the pattern are assigned to local variables in the arm's block, and control enters the block.

... more about place expressions

在你的例子中,检查者 *x.lock().unwrap() 是一个值表达式,因此守卫的生命周期与你的主分支的生命周期相同。因此你会陷入僵局,在它已经被你自己的 if let

锁定后再次尝试 .lock() 互斥