考虑到这种模式匹配的情况:
foo match {
case x if expensiveCalculation(x).nonEmpty => // do something with expensiveCalculation(x)
...
}
是否可以在=>之后“标记”或重复使用昂贵的计算(x)?
理想情况下,我期待的是:
foo match {
case x val ec = expensiveCalculation(x); if ec.nonEmpty => // do something with ec
...
}
最佳答案 您可以为x的类型编写一个提取器(这里假设为InputType):
object Expensive {
def unapply(x: InputType): Option[OutputType] = expensiveCalculation(x)
}
现在,您可以在模式匹配中使用它:
fooList match {
case _ :: Expensive(output) :: _ => ...
case _ :: x :: _ => ...
}
但是,如果您为许多计算执行此操作(这需要每次都定义一个提取器),这是一种执行您想要的操作的麻烦方式.
您可以通过定义以下内容一劳永逸地执行此操作:
case class Comput[-A, +B](f: A => Option[B]) {
def unapply(a: A): Option[B] = f(a)
}
现在,您可以按如下方式使用它:
val intString = "10"
val IntOf = Comput[String, Int](s => Try(s.toInt).toOption)
intString match {
case IntOf(x) => x
case other => 0
} // returns 10: Int
但是,在模式匹配中使用它之前,您无法省去定义IntOf(编译器解析器似乎丢失了).