在下面的示例程序中,有没有什么方法可以避免定义map2
?
fn map2<T, U, V, F: Fn(T, U) -> V>(f: F, a: Option<T>, b: Option<U>) -> Option<V> {
match a {
Some(x) => match b {
Some(y) => Some(f(x, y)),
None => None,
},
None => None,
}
}
fn main() {
let a = Some(5);
let b = Some(10);
let f = |a, b| {
a + b
};
let res = map2(f, a, b);
println!("{:?}", res);
// prints Some(15)
}
字符串
对于也会说Haskell的人来说,我想这个问题也可以表述为“在Rust中,我们可以使用什么工具来代替liftM2?”“
8条答案
按热度按时间ghg1uchk1#
我偶然发现了这个线程,并没有找到基于
zip
的最明显、最直接的一行程序解决方案。字符串
还有一个
zip_with
变体,现在标记为 unstable。型
xfb7svmp2#
其中的几个解决方案,现在与impl OptionExtension。改编自Shepmaster提出的解决方案:
字符串
还可以添加其他操作,例如fn合并_with sub、div、…
参见Rust Playground。
main()函数:
型
输出:
型
tcomlyy63#
我不相信有一个直接的函数等价于
liftM2
,但是你可以像这样合并Option::and_then
和Option::map
:字符串
输出量:
型
oyt4ldly4#
从Rust 1.46.0开始,你可以使用
Option::zip
:字符串
这可以与
Option::map
组合,如其他答案所示:型
w7t8yxp55#
我不知道你是否能找到一条线(编辑:哦,接受的答案很好地将其减少到一行),但您可以通过匹配元组来避免嵌套的
match
:字符串
bybem2ql6#
您可以将immediately invoked function expression (IIFE)与
?
(try)运算符结合使用:字符串
在未来,你可以使用 try blocks:
型
参见:
l3zydbqr7#
字符串
选项一
型
选项二
型
选项三
型
irtuqstp8#
您可以使用
Option
s可以迭代的事实。迭代这两个选项,将它们压缩在一起,并将结果迭代器Map到函数上。字符串
这需要修改
f
,因此参数被合并为单个元组参数。如果不修改f
,直接Map到|args| f.call(args)
上也是可能的,但这样就必须Map到specify the closure kind off
。