scala 用偏函数分解模式匹配中的常见情况

rslzwgfq  于 2022-12-13  发布在  Scala
关注(0)|答案(1)|浏览(130)

我经常使用分部函数来分离出异常处理中的常见子句。例如:

val commonHandler: PartialFunction[Throwable, String] = {
  case ex: InvalidClassException => "ice"
}

val tried = try {
  throw new Exception("boo")
}
catch commonHandler orElse {
  case _:Throwable => "water"
}

println(tried) // water

当然,我希望match关键字也需要一个分部函数,我应该能够做如下的事情:

val commonMatcher: PartialFunction[Option[_], Boolean] = {
    case Some(_) => true
    case None => false
  }

  Some(8) match commonMatcher // Compilation error

我做错了什么?

dgsult0t

dgsult0t1#

match是一个关键字,而不是一个方法,它的语法不接受其右侧的部分函数(见下文)。然而,存在一个pipe方法(从Python 2.13开始),它和mapforeach一样,接受部分函数。因此,你可以写为:

import scala.util.chaining._

Some(8).pipe(commonMatcher)

对此进行了一些讨论(参见Pre SIP: Demote match keyword to a method),并且有一个PR,它使得使用match更像一个方法(Change match syntax #7610),带有一个点,但语法仍然是match关键字需要后跟case子句,参见https://docs.scala-lang.org/scala3/reference/syntax.html

InfixExpr         ::=  ... other variants ommitted here ...
                    |  InfixExpr MatchClause

SimpleExpr        ::=  ... other variants ommitted here ...
                    |  SimpleExpr ‘.’ MatchClause

MatchClause       ::=  ‘match’ <<< CaseClauses >>>

CaseClauses       ::=  CaseClause { CaseClause }
CaseClause        ::=  ‘case’ Pattern [Guard] ‘=>’ Block

将此语法与catch语法进行比较:

Expr1             ::=  ... other variants ommitted here ...
                    |  ‘try’ Expr Catches [‘finally’ Expr]

Catches           ::=  ‘catch’ (Expr | ExprCaseClause)

相关问题