Rust 临时变量的生命周期

https://doc.rust-lang.org/book/ch20-02-multithreaded.html

Rust 关于 let 语句中以下划线变量名需要注意的一个点, _, _var, var 三者在生命周期上的区别

The Rust Programming Language 的第 20 章第 2 节的最后,对比了下面两段代码的区别

impl Worker {
    fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
        let thread = thread::spawn(move || loop {
            let job = receiver.lock().unwrap().recv().unwrap();

            println!("Worker {} got a job; executing.", id);

            job();
        });

        Worker { id, thread }
    }
}

VS

impl Worker {
    fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
        let thread = thread::spawn(move || {
            while let Ok(job) = receiver.lock().unwrap().recv() {
                println!("Worker {} got a job; executing.", id);

                job();
            }
        });

        Worker { id, thread }
    }
}

This code compiles and runs but doesn’t result in the desired threading behavior: a slow request will still cause other requests to wait to be processed. The reason is somewhat subtle: the Mutex struct has no public unlock method because the ownership of the lock is based on the lifetime of the MutexGuard within the LockResult<MutexGuard> that the lock method returns. At compile time, the borrow checker can then enforce the rule that a resource guarded by a Mutex cannot be accessed unless we hold the lock. But this implementation can also result in the lock being held longer than intended if we don’t think carefully about the lifetime of the MutexGuard.

The code in Listing 20-20 that uses let job = receiver.lock().unwrap().recv().unwrap(); works because with let, any temporary values used in the expression on the right hand side of the equals sign are immediately dropped when the let statement ends. However, while let (and if let and match) does not drop temporary values until the end of the associated block. In Listing 20-21, the lock remains held for the duration of the call to job(), meaning other workers cannot receive jobs.

文中说 let 语句结束时,等号右边的所有临时变量都会被 drop. 而 while let(还有 if let 和 match) 不会立即 drop 临时变量,而是等到它们的代码块结束后才 drop

开始实验:


struct Foo{}
struct Bar{}

impl Foo{
    fn bar(&self) -> Result<Bar, ()> {
        Ok(Bar{})
    }
}

impl Drop for Foo {
    fn drop(&mut self) {
        println!("drop Foo");
    }
}
impl Drop for Bar {
    fn drop(&mut self) {
        println!("drop Bar");
    }
}

fn main() {

    let result: Result<_, ()> = Ok(Foo{});
    while let _ = result.unwrap().bar().unwrap(){
        println!("in while...");
        break;
    }
    println!("out of while");

    let result2: Result<_, ()> = Ok(Foo{});
    let _ = result2.unwrap().bar().unwrap();
    println!("unwrapped result");
}

输出:

in while...
drop Bar
drop Foo
out of while
drop Bar
drop Foo
unwrapped result

posted on 2022-06-06 00:12  明天有风吹  阅读(220)  评论(0编辑  收藏  举报

导航

+V atob('d2h5X251bGw=')

请备注:from博客园