当将值分配给下划线模式时会发生什么?

28
这是 Rust 测验 28 的一个问题:
struct Guard;

impl Drop for Guard {
    fn drop(&mut self) {
        print!("1");
    }
}

fn main() {
    let _guard = Guard;
    print!("3");
    let _ = Guard;
    print!("2");
}

这段代码会打印出3121,在main函数的第三行,将值赋给_表示立即丢弃。然而,当使用以下代码将所有权转移给_时:

struct Guard;

impl Drop for Guard {
    fn drop(&mut self) {
        print!("1");
    }
}

fn main() {
    let _guard = Guard;
    print!("3");
    let _ = _guard;
    print!("2");
}

它打印出321,这意味着Guard没有立即释放,而_拥有Guard

所以我不确定像这样将互斥锁分配给_let _ = Mutex::lock().unwrap()时,它是否会立即释放互斥锁?


2
还要注意,语句guard;会移动(并因此丢弃)guard,而let _ = guard;则不会导致移动。函数std::mem::drop()实际上是多余的——drop(x);x;是完全等价的。 - Sven Marnach
1个回答

38

_ 表示“不绑定此值”。当您在现场创建新值时,这意味着该值立即被丢弃,就像您所说的那样,因为没有绑定来拥有它。

当您将其与已绑定到变量的内容一起使用时,该值不会移动,这意味着变量保留所有权。因此,此代码有效。

let guard = Guard;
let _ = guard;
let _a = guard; // `guard` still has ownership

这也可以运行。

let two = (Guard, Guard);
print!("4");
let (_a, _) = two;
print!("3");
let (_, _b) = two;
print!("2");

这在匹配语句中更有用,当您想要在匹配后使用原始值时,如果内部值被移动,则通常不起作用。

let res: Result<Guard, Guard> = Ok(Guard);
match res {
    Ok(ok) => drop(ok),
    Err(_) => drop(res), // do something with the whole `Result`
}

如果你将第二个分支改为Err(_e),你会得到使用了部分移动的值:`res`


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接