要从模式匹配中返回选项,请使用Try?

时间:2015-09-04 13:01:35

标签: scala pattern-matching

我有很多模式匹配代码,如下所示:如果某些Foo匹配,则返回Some Bar,否则为None,并且有很多Foos的{​​{1}}和Bars的长构造函数。类似的东西:

y match {
   case Foo1(z) => Some(Bar1(z))
   case Foo2(z) => Some(Bar2(z))
   case Foo3(z) => Some(Bar3(z))
   case Foo4(z) => Some(Bar4(z))
   case _ => None
}

在实际代码中,箭头右侧的构造函数更复杂,并且有更多的情况。

现在,为了摆脱重复的选项构造函数(Some),我可以这样做:

Try( 
   y match {
     case Foo1(z) => Bar1(z)
     case Foo2(z) => Bar2(z)
     case Foo3(z) => Bar3(z)
     case Foo4(z) => Bar4(z)
  }
).toOption

这对我来说看起来更清晰,从语义角度看它是合理的,因为case _实际上是一种不应该发生的情况,因此将其建模为异常似乎是合理的。请注意,重复的Somes会让我感到烦恼,而不是最后的case

我的问题是,我不知道后一种方法是否存在某些(例如性能)惩罚。

1 个答案:

答案 0 :(得分:9)

第二个版本的可读性较差,而且不太正确*。如果您要将错误丢弃到Try,则使用None没有太大意义。 Try只有 才能捕获匹配错误并将其转换为None,但您可以使用case _ => None进行匹配。

Try中会有更多的开销包装,但不够重要。首先要有正确性和可读性。

如果确实不希望出现这种情况,请考虑将y包裹在Option并使用collect

Option(y) collect {
   case Foo1(z) => Bar1(z)
   case Foo2(z) => Bar2(z)
   case Foo3(z) => Bar3(z)
   case Foo4(z) => Bar4(z)
}

collect上使用Option会将案例包装在Some中定义的部分函数中,任何不匹配的案例都将变为None。< / p>

* 正确,我的意思是广泛接受使用Try