如果 Rust 的 Option
就好了提供了一些额外的便利方法,例如 Option#flatten
和 Option#flat_map
, 其中flatten
会减少 <Option<Option<T>>
至 Option<T>
, 和 flat_map
会像 map
一样工作, 但采用返回 Option
的方法/闭包并将其压平。
flat_map
非常简单:
fn opt_flat_map< T, U, F: FnOnce(T) -> Option<U> >(opt: Option<T>, f: F) -> Option<U> {
match opt {
Some(x) => f(x),
None => None
}
}
flatten
更复杂,我真的不知道如何去定义它。它可能看起来像:
fn opt_flatten<T, U>(opt: Option<T>) -> Option<U> {
match opt {
Some( Some(x) ) => flatten_option( Some(x) ),
_ => opt
}
}
但这肯定行不通。有什么想法吗?
此外,我将如何在 Option
上实现这些方法?枚举,以便我可以在 Option
上本地使用它们实例?我知道我需要在 impl OptionExts for Option<T>
附近的某处添加类型签名,但我不知所措......
希望这是有道理的,我为我不精确的术语道歉——我是 Rust 的新手。
最佳答案
这些可能已经存在,只是名称与您期望的不同。检查docs for Option .
您将更正常地看到 flat_map
作为 and_then
:
let x = Some(1);
let y = x.and_then(|v| Some(v + 1));
做你想做的更大的方法是用你想要的方法声明一个trait,然后为Option
实现它:
trait MyThings {
fn more_optional(self) -> Option<Self>;
}
impl<T> MyThings for Option<T> {
fn more_optional(self) -> Option<Option<T>> {
Some(self)
}
}
fn main() {
let x = Some(1);
let y = x.more_optional();
println!("{:?}", y);
}
对于flatten
,我可能会这样写:
fn flatten<T>(opt: Option<Option<T>>) -> Option<T> {
match opt {
None => None,
Some(v) => v,
}
}
fn main() {
let x = Some(Some(1));
let y = flatten(x);
println!("{:?}", y);
}
但是如果你想要一个特质:
trait MyThings<T> {
fn flatten(self) -> Option<T>;
}
impl<T> MyThings<T> for Option<Option<T>> {
fn flatten(self) -> Option<T> {
match self {
None => None,
Some(v) => v,
}
}
}
fn main() {
let x = Some(Some(1));
let y = x.flatten();
println!("{:?}", y);
}
Would there be a way to allow flatten to arbitrary depth
参见 How do I unwrap an arbitrary number of nested Option types?
关于rust - 如何在 Option 上实现一些方便的方法(例如 flat_map、flatten)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28566531/