1 个不稳定版本
0.1.0 | 2024年3月21日 |
---|
#964 在 Rust 模式
23KB
246 行
once-option
once_option
包定义了一个类型,OnceOption
,以及它的构建辅助函数,OnceOption()
。
该包是 no_std
。
OnceOption
表示一个可选值。与 Option
不同,空的 OnceOption
不能重新设置为包含值。
此外,OnceOption
实现 Deref
和 DerefMut
,因此其内容可以不使用模式匹配(但隐式展开)来访问。
它支持与其他相同类型的 OnceOption
进行比较(PartialEq
、Eq
、Ord
或 PartialOrd
),只要包含的类型也实现了这些特性。此外,如果包含的类型是 Hash
,则它可以作为哈希键使用。
如果包含的类型是 Display
,则它支持显示,并将所有格式化特性(除了 Debug
和 Pointer
)传递给其包含的类型。
理由
OnceOption
的主要但不是唯一目的是简化和管理具有消耗值方法的成员的析构。
例如,以下代码将无法编译
// Warning: this code does *NOT* compile
use std::{thread, time::Duration};
struct SomeType {
handle: thread::JoinHandle<u32>,
}
impl SomeType {
fn new() -> Self {
Self {
handle: thread::spawn(|| {
thread::sleep(Duration::from_secs(5));
42
}),
}
}
}
impl Drop for SomeType {
fn drop(&mut self) {
println!("The answer is {}", self.handle.join());
}
}
编译器将失败并显示类似于以下错误(尝试!)
Compiling playground v0.0.1 (/playground)
error[E0507]: cannot move out of `self.handle` which is behind a mutable reference
--> src/lib.rs:22:38
|
22 | println!("The answer is {}", self.handle.join().unwrap());
| ^^^^^^^^^^^ ------ `self.handle` moved due to this method call
| |
| move occurs because `self.handle` has type `JoinHandle<u32>`, which does not implement the `Copy` trait
|
note: `JoinHandle::<T>::join` takes ownership of the receiver `self`, which moves `self.handle`
--> /playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/thread/mod.rs:1649:17
|
1649 | pub fn join(self) -> Result<T> {
| ^^^^
For more information about this error, try `rustc --explain E0507`.
error: could not compile `playground` (lib) due to 1 previous error
OnceOption
可以用来修复此问题,同时只需对代码进行最小修改
use once_option::OnceOption;
use std::{thread, time::Duration};
struct SomeType {
handle: OnceOption<thread::JoinHandle<u32>>,
}
impl SomeType {
fn new() -> Self {
Self {
handle: thread::spawn(|| {
thread::sleep(Duration::from_secs(5));
42
}).into(),
}
}
fn thread_id(&self) -> thread::ThreadId {
self.handle.thread().id()
}
}
impl Drop for SomeType {
fn drop(&mut self) {
println!("The answer is {}", self.handle.take().join().unwrap());
}
}
表示
OnceOption<T>
与 Option<T>
具有相同的 ABI;这意味着 OnceOption<T>
具有与 Option<T>
相同的大小、对齐方式和函数调用 ABI。
这一点的含义是,所有由 Option<T>
提供的 ABI 保证(即在某些条件下从 T 转换),也适用于 OnceOption<T>
。有关更多详细信息,请参阅 Option
的文档。