视频地址
头条地址:https://www.ixigua.com/i
B站地址:https://www.bilibili.com/video/av?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主要有以下一些用法:
- 初始化值;
- 作为在整个输入范围内没有定义的函数的返回值;
- 作为返回值,用
None
表示出现的简单错误; - 作为结构体的可选字段;
- 作为结构体中可借出或者是可载入的字段;
- 作为函数的可选参数;
- 代表空指针;
- 用作复杂情况的返回值。
此处,我们举例说明一下“作为结构体可借出或者是可载入的字段”。
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,成功解决问题。
方法
- is_some
pub fn is_some(&self) -> bool
当Option中有值时,返回true。
- is_none
pub fn is_none(&self) -> bool
当Option为None时,返回true。
- contains
pub fn contains<U>(&self, x: &U) -> bool where U: PartialEq<T>,
当Some中包含给定的值时,返回true。这个是nightly API。
//示例 #![feature(option_result_contains)] let x: Option<u32> = Some(2); assert_eq!(x.contains(&2), true); let x: Option<u32> = Some(3); assert_eq!(x.contains(&2), false);
- as_ref
pub fn as_ref(&self) -> Option<&T>
将
&Option<T>
转换为Option<&T>
//例子 let text: Option<String> = Some("Hello, world!".to_string()); let text_length: Option<usize> = text.as_ref().map(|s| s.len()); println!("still can print text: {:?}", text);
- take
pub fn take(&mut self) -> Option<T>
把值从Option中拿出来,留下None。
let mut x = Some(2); let y = x.take(); assert_eq!(x, None); assert_eq!(y, Some(2)); let mut x: Option<u32> = None; let y = x.take(); assert_eq!(x, None); assert_eq!(y, None);
- copied
pub fn copied(self) -> Option<T>
从
Option<&T>
得到Option<T>
(通过复制来实现)let x = 12; let opt_x = Some(&x); assert_eq!(opt_x, Some(&12)); let copied = opt_x.copied(); assert_eq!(copied, Some(12));
- cloned
pub fn cloned(self) -> Option<T>
从
Option<&T>
得到Option<T>
(通过克隆来实现)let x = 12; let opt_x = Some(&x); assert_eq!(opt_x, Some(&12)); let cloned = opt_x.cloned(); assert_eq!(cloned, Some(12));
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/rustbc/1704.html