如果 RustOption提供了一些额外的便利方法,比如Option#flattenand Option#flat_map,那么这将是很好的, whereflatten会将 an 减少<Option<Option<T>>到Option<T>,并且flat_map会像 一样工作map,但采用返回 anOption并将其展平的方法/闭包。
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
}
}
Run Code Online (Sandbox Code Playgroud)
flatten更复杂,我真的不知道如何定义它。它可能看起来像:
fn opt_flatten<T, U>(opt: Option<T>) -> Option<U> {
match opt {
Some( Some(x) ) => flatten_option( Some(x) ),
_ => opt
}
}
Run Code Online (Sandbox Code Playgroud)
但这肯定行不通。有什么想法吗?
另外,我将如何在Option枚举上实现这些方法,以便我可以在Option实例上本地使用它们?我知道我需要在周围的某个地方添加类型签名impl OptionExts for Option<T>,但我不知所措......
希望这是有道理的,我为我不精确的术语道歉——我是 Rust 的新手。
fn flatten<T>(x: Option<Option<T>>) -> Option<T> {
x.unwrap_or(None)
}
Run Code Online (Sandbox Code Playgroud)
就我而言,我正在处理Option-returning 方法unwrap_or_else并忘记了普通or_else方法。
这些可能已经存在,就像您期望的名称不同。检查Option的文档。
你会flat_map更正常地看到and_then:
let x = Some(1);
let y = x.and_then(|v| Some(v + 1));
Run Code Online (Sandbox Code Playgroud)
做你想做的更大的方法是用你想要的方法声明一个特征,然后实现它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);
}
Run Code Online (Sandbox Code Playgroud)
对于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);
}
Run Code Online (Sandbox Code Playgroud)
但如果你想要一个特质:
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);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法允许展平到任意深度
| 归档时间: |
|
| 查看次数: |
1606 次 |
| 最近记录: |