使用模式匹配参数的闭包组合 Option<Enum>
Composing Option<Enum> with closures that pattern-match arguments
我有一个枚举,其中包含两个不同的可能 "types" 和一个可能 return 其中任何一个的函数,包含在 Option
:
中
enum Possibilities {
First(i32),
Second(String),
}
use Possibilities::*;
fn some_poss() -> Option<Possibilities> {
Some(Second(String::from("hi")))
}
我想对 some_poss
的结果应用一个操作,但是这个操作只对枚举的一种可能性有意义,否则它应该 return None
。例如:
let a: Option<i32> = some_poss().and_then(|poss| if let First(x) = poss {
Some(x * 2)
} else {
None
});
如何简洁地组合这个操作?可以这样写吗?
// Compile error: pattern `Second(_)` not covered
let b: Option<i32> = some_poss().map(|First(x)| x * 2);
处理这种特定情况的最佳方法是在 enum
上创建一个专门用于检索一个变体的方法。有点像 Result::ok
.
enum Possibilities {
First(i32),
Second(String),
}
use Possibilities::*;
impl Possibilities {
fn first(self) -> Option<i32> {
match self {
Possibilities::First(x) => Some(x),
_ => None,
}
}
}
这样您就可以像这样实现您的功能:
some_fun().and_then(|p| p.first()).map(|x| x * 2)
// or, if you prefer this style:
some_fun().and_then(Possibilities::first).map(|x| x * 2);
这使得每个步骤都在做什么 - some_poss
得到一个 Option<Possiblities>
,然后 first()
从那个 Possibilities
得到一个 Option<i32>
,然后然后 and_then
将 Option<Option<i32>>
折叠成 Option<i32>
.
我有一个枚举,其中包含两个不同的可能 "types" 和一个可能 return 其中任何一个的函数,包含在 Option
:
enum Possibilities {
First(i32),
Second(String),
}
use Possibilities::*;
fn some_poss() -> Option<Possibilities> {
Some(Second(String::from("hi")))
}
我想对 some_poss
的结果应用一个操作,但是这个操作只对枚举的一种可能性有意义,否则它应该 return None
。例如:
let a: Option<i32> = some_poss().and_then(|poss| if let First(x) = poss {
Some(x * 2)
} else {
None
});
如何简洁地组合这个操作?可以这样写吗?
// Compile error: pattern `Second(_)` not covered
let b: Option<i32> = some_poss().map(|First(x)| x * 2);
处理这种特定情况的最佳方法是在 enum
上创建一个专门用于检索一个变体的方法。有点像 Result::ok
.
enum Possibilities {
First(i32),
Second(String),
}
use Possibilities::*;
impl Possibilities {
fn first(self) -> Option<i32> {
match self {
Possibilities::First(x) => Some(x),
_ => None,
}
}
}
这样您就可以像这样实现您的功能:
some_fun().and_then(|p| p.first()).map(|x| x * 2)
// or, if you prefer this style:
some_fun().and_then(Possibilities::first).map(|x| x * 2);
这使得每个步骤都在做什么 - some_poss
得到一个 Option<Possiblities>
,然后 first()
从那个 Possibilities
得到一个 Option<i32>
,然后然后 and_then
将 Option<Option<i32>>
折叠成 Option<i32>
.