其他分享
首页 > 其他分享> > Rust 临时变量的生命周期

Rust 临时变量的生命周期

作者:互联网

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

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

标签:生命周期,变量,unwrap,drop,Worker,job,let,Foo,Rust
来源: https://www.cnblogs.com/hangj/p/16345715.html