考虑两个语义等效的代码段:
let x = Mutex::new(0);
if *x.lock().unwrap() == 0 {
*x.lock().unwrap() = 1;
}
Run Code Online (Sandbox Code Playgroud)
let x = Mutex::new(0);
if let 0 = *x.lock().unwrap() {
*x.lock().unwrap() = 1;
}
Run Code Online (Sandbox Code Playgroud)
第一个按预期运行,而第二个则死锁。为什么守卫析构函数被运行if而不是被运行if let?在哪里可以找到有关此行为的文档?
答案可以在 上找到docs.rust-lang.org。具体可以参考if let一篇文章,里面说:
表达式
if let等效于match如下表达式:
if let PATS = EXPR { /* body */ } else { /*else */ }相当于
match EXPR { PATS => { /* body */ }, _ => { /* else */ } }
转到match文章后,据说
根据检查表达式是位置表达式还是值表达式,匹配的行为会有所不同。
如果被检查者表达式是值表达式,则首先将其计算到临时位置,然后将结果值顺序与手臂中的模式进行比较,直到找到匹配。选择具有匹配模式的第一个臂作为匹配的分支目标,该模式绑定的任何变量都被分配给该臂块中的局部变量,并且控制进入该块。
...有关地点表达的更多信息
在您的情况下,scrutinee*x.lock().unwrap()是一个值表达式,因此守卫的生命周期与主分支的生命周期相同。因此你会陷入僵局,.lock()在它已经被你自己锁定后再次尝试互斥if let
| 归档时间: |
|
| 查看次数: |
60 次 |
| 最近记录: |