Video address
Headline address: https://www.ixigua.com/i6765442674582356483
Address of station B: https://www.bilibili.com/video/av7806209? P = 1
Netease cloud classroom address: https://study.163.com/course/introduction.htm? Courseid = 1209596906 yuan / coursedetail? Tab = 1
github address
introduce
The option type represents an optional value. Each option is either a value in a certain or a None. Option is defined as follows:
pub enum Option<T> { None, Some(T), }
usage
Option s are mainly used in the following ways:
-
Initialization value;
-
As the return value of a function not defined in the entire input range;
-
As the return value, use None to indicate the simple error;
-
As an optional field of the structure;
-
As a loanable or loadable field in the structure;
-
As optional parameter of function;
-
Represents a null pointer;
-
Used as a return value for complex situations.
Here, we give an example of "fields that can be lent or loaded as structures".
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();//Error reporting, unable to compile, and thread unable to implement copy trace println!("worker thread finished!"); } } } fn main() { let _pool = ThreadPool::new(3); println!("Hello, world!"); }
In the above example, an incomplete thread pool is implemented. In worker, a field is the handle of thread. When the thread pool object drop s, you cannot use the reference of the member in the MUT object (that is, take out the worker through & mut self. Workers, and call worker.thread.join()). To solve this problem, we can modify the worker structure as follows:
struct Worker { // thread: thread::JoinHandle<()>, thread: Option<thread::JoinHandle<()>>, }
The complete code is:
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() {//Here, take the thread out of the Option of the thread field of the Worker, and use "Option type as the loanable or loadable field in the structure" thread.join().unwrap(); println!("worker thread finished!"); } } } } fn main() { let _pool = ThreadPool::new(3); println!("Hello, world!"); }
In the drop implementation of ThreadPool, the thread is removed from worker through the take method of option, and then join is invoked to solve the problem successfully.
Method
-
is_some
pub fn is_some(&self) -> bool
Returns true when there is a value in Option.
-
is_none
pub fn is_none(&self) -> bool
Returns true when Option is None.
-
contains
pub fn contains<U>(&self, x: &U) -> bool where U: PartialEq<T>,
Returns true when the given value is included in Some. This is the nightly API.
//Example #![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>
Convert & option < T > to option < & T >
//Example 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>
Take the value out of Option and leave 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>
Get option < T > from option < & T > (by copying)
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>
Get option < T > from option < & T > (by cloning)
let x = 12; let opt_x = Some(&x); assert_eq!(opt_x, Some(&12)); let cloned = opt_x.cloned(); assert_eq!(cloned, Some(12));