RUST编程

RUST编程知识拾遗:Option 学习

2020-04-09  本文已影响0人  令狐壹冲

视频地址

头条地址:https://www.ixigua.com/i6765442674582356483
B站地址:https://www.bilibili.com/video/av78062009?p=1
网易云课堂地址:https://study.163.com/course/introduction.htm?courseId=1209596906#/courseDetail?tab=1

github地址

github地址

介绍

Option类型代表了一个可选的值,每个Option要么是一个Some中包含一个值,要么是一个None。Option的定义如下:

pub enum Option<T> {
    None,
    Some(T),
}

用法

Option主要有以下一些用法:

此处,我们举例说明一下“作为结构体可借出或者是可载入的字段”。

use std::thread;
use std::time::Duration;

struct Worker {
    thread: thread::JoinHandle<()>,
}

impl Worker {
    fn new() -> Worker {
        let thread = thread::spawn(move || {
            println!("start sleep 10 secs ...");
            thread::sleep(Duration::from_secs(10));
        });
        Worker {
            thread: thread,
        }
    }
}

struct ThreadPool {
    workers: Vec<Worker>,
}

impl ThreadPool {
    fn new(size: usize) -> ThreadPool {
        assert!(size > 0);
        let mut workers = Vec::with_capacity(size);
        for _ in 0..size {
            workers.push(Worker::new());
        }

        ThreadPool { workers }
    }
}

impl Drop for ThreadPool {
    fn drop(&mut self) {
        for worker in &mut self.workers {
            worker.thread.join().unwrap();//报错,无法编译,thread也无法实现copy trait
            println!("worker thread finished!");
        }
    }
}

fn main() {
    let _pool = ThreadPool::new(3);
    println!("Hello, world!");
}

上述例子中,实现了一个不完整的线程池,在Worker中,有一个字段为线程的句柄。当线程池对象drop时,无法使用mut对象中成员的引用(即通过&mut self.workers取出worker,在调用worker.thread.join())。为了解决此问题,我们可以将Worker结构体修改如下:

struct Worker {
    // thread: thread::JoinHandle<()>,
    thread: Option<thread::JoinHandle<()>>,
}

完整代码为:

use std::thread;
use std::time::Duration;

struct Worker {
    // thread: thread::JoinHandle<()>,
    thread: Option<thread::JoinHandle<()>>,
}

impl Worker {
    fn new() -> Worker {
        let thread = thread::spawn(move || {
            println!("start sleep 10 secs ...");
            thread::sleep(Duration::from_secs(10));
        });
        Worker {
            // thread: thread,
            thread: Some(thread),
        }
    }
}

struct ThreadPool {
    workers: Vec<Worker>,
}

impl ThreadPool {
    fn new(size: usize) -> ThreadPool {
        assert!(size > 0);
        let mut workers = Vec::with_capacity(size);
        for _ in 0..size {
            workers.push(Worker::new());
        }

        ThreadPool { workers }
    }
}

impl Drop for ThreadPool {
    fn drop(&mut self) {
        for worker in &mut self.workers {
            // worker.thread.join().unwrap();
            // println!("worker thread finished!");
            
            if let Some(thread) = worker.thread.take() {//此处将thread从Worker的thread字段的Option中拿出来,使用了“Option类型作为结构体中可借出或者是可载入的字段”
                thread.join().unwrap();
                println!("worker thread finished!");
            }
        }
    }
}

fn main() {
    let _pool = ThreadPool::new(3);
    println!("Hello, world!");
}

在ThreadPool的drop实现中,通过option的take方法,将thread从worker中移出,然后调用join,成功解决问题。

方法

上一篇 下一篇

猜你喜欢

热点阅读