函数参数块中的互斥锁永远解锁

问题描述 投票:0回答:1

此代码立即完成(playground):

use std::sync::Mutex;

fn f(_: usize, _: usize) {}

fn main() {
    let m = Mutex::new(0);

    let i = { *m.lock().unwrap() };
    let j = { *m.lock().unwrap() };
    f(i, j);
}

此代码也立即完成(playground):

use std::sync::Mutex;

fn f(_: usize, _: usize) {}

fn main() {
    let m = Mutex::new(0);

    f(
        {
            let i = *m.lock().unwrap();
            i
        },
        {
            let j = *m.lock().unwrap();
            j
        },
    );
}

这段代码,我认为在语义上与上面的代码相同,永远阻塞(playground):

use std::sync::Mutex;

fn f(_: usize, _: usize) {}

fn main() {
    let m = Mutex::new(0);

    f({ *m.lock().unwrap() }, { *m.lock().unwrap() });
}

为什么?

rust mutex
1个回答
0
投票

发生这种情况是由于 临时范围

表达式的临时作用域是用于临时变量的作用域,该临时变量在位置上下文中使用时保存该表达式的结果,除非它被提升。

除了生命周期扩展之外,表达式的临时作用域是包含该表达式的最小作用域,并且是以下之一:

  • 整个功能。
  • 声明。
  • if
    while
    loop
    表达式的主体。
  • else
    表达式的
    if
    块。
  • if
    while
    表达式或
    match
    保护的条件表达式。
  • 火柴臂的身体表情。
  • 惰性布尔表达式的第二个操作数。

在第三个示例中,适用于临时匹配守卫的最小范围是包含对

f
的调用的整个语句。 (请注意,块中的最终表达式不是语句。

因此,您的第二个和第三个代码示例在语义上“不”相同。在第三个示例中,在块表达式中创建的互斥锁保护的生命周期扩展到调用

f 的整个语句,但在第二个示例中,互斥锁保护的生命周期仅限于 let

 语句。
	

© www.soinside.com 2019 - 2024. All rights reserved.