2015-09-04 77 views
1

我有很多的模式匹配代码如下所示:如果某些Foo的比赛中,Bar一个Some返回,否则None,并且有很多Foos和长构造函数Bars。例如:要从模式匹配中返回Option,请使用Try?

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

我的问题是,是否有一些(例如表现)惩罚后一种方法,我不知道。

回答

9

第二个版本的可读性较差,而且不太正确*。使用Try没有太大的意义,如果你只是想抛弃错误NoneTry只有那里捕捉匹配错误,并将它们转换为None,但你可以用case _ => None这样做。

Try会有稍微更多的开销环绕,但不够重要。正确性和可读性应该是第一位的。

如果你真的不想有额外的情况下,可以考虑在Option包装y和使用collect

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

Option使用collect将包装的情况下,在部分功能是在Some中定义,任何不匹配的情况将变为None


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

+0

我的重点是可读性(这不像听起来那么客观),它是额外的一些我觉得分散注意力的东西,而不是最后一种情况。你的版本会处理无与伦比的情况吗?如果是这样,我觉得它是一个非常好的解决方案。我看到你关于Try的观点。 – DCS

+0

我关于可读性的观点是,在'Try'中包装'match'会掩盖它的目的,是的。我会更详细地编辑。 –