是否可以使用分部函数分解Scala匹配语句



我有一个匹配语句,如下所示:

i match {
case x if x == 0 ⇒
romanNumeral
case x if x >= 1000 ⇒
this.roman(i - 1000, s"${romanNumeral}M")
case x if x >= 900 ⇒
this.roman(i - 900, s"${romanNumeral}CM")
// etc.

根据它的格式,它可能是大约30行冗余代码。所以我想知道是否有可能让这个代码更枯燥。

所以我创建了一个部分函数:

private def toRoman(upperGuard: Int, token: String, romanNumeral: String): String = {
case value: Int if value >= upperGuard ⇒
this.roman(upperGuard - 1, s"$romanNumeral$token")
}

然后我试着把它包括在上面的匹配器中,比如:

i match {
case x if x == 0 ⇒
romanNumeral
toRoman(1000, "M", romanNumeral)
toRoman(900, "CM", romanNumeral)
// etc.

但这不起作用,因为Scala的编译器没有识别出这些函数是它所寻找的case语句。

有什么办法让它发挥作用吗?

您可以将案例创建为部分函数:

private def toRoman(upperGuard: Int, token: String, romanNumeral: String): PartialFunction[Int, String] = {
case value if value >= upperGuard =>
this.roman(upperGuard - 1, s"$romanNumeral$token")
}
val firstCase: PartialFunction[Int, String] = {
case x if x == 0 => romanNumeral
}

然后这样写:

val toRomanPartialFunction = firstCase
.orElse(toRoman(1000, "M", romanNumeral))
.orElse(toRoman(900, "CM", romanNumeral))

之后,你可以像使用常规功能一样使用它:

toRomanPartialFunction.apply(443) 
toRomanPartialFunction(443) 

所以你基本上想减少代码的重复性,首先是:

Scala的编译器不将这些函数识别为case语句,因为它们是函数
  • 第二,这个函数实际上不是一个偏函数
  • 最后,如果你能找到一种方法,通过分组到某种函数中来减少代码行,就像你做得很好,但我不觉得它们是多余的,除非你能像我说的那样用函数重做
  • Ps:该函数不会像那样做一些事情

    您没有模式匹配表达式,您只是在编写if else语句。如果你想返回一个函数,你可以写:x => this.something(x,"foo-bar")你不需要case x。如果在LHScase x上只有一个表达式,则不需要模式匹配,只需使用if else即可。没有类层次结构的模式匹配是没有意义的。

    最新更新