所以,假设我想为PartialFunction
提供一个"全部"的回退:
val foo: PartialFunction[Int, String] = { case 1 => "foo" }
val withDefault = foo orElse { _.toString }
这不会编译:missing parameter type for expanded function ((x$1) => x$1.toString)
.这:
val withDefault = foo orElse { case x: Int => x.toString }
也不编译(相同的错误)。
这:
val withDefault = foo orElse { (x: Int) => x.toString }
失败并显示type mismatch; found : Int => String; required: PartialFunction[?,?]
我能找到使其工作的唯一方法是详细说明整个事情:
val withDefault = foo orElse PartialFunction[Int, String] { _.toString }
有没有更好的语法?我的意思是,一个不必告诉它我正在将部分函数从 int 传递到字符串到它期望从 in 到字符串接收部分函数的位置。这一点也不模棱两可,我为什么要这样做?
也许你需要applyOrElse
:
val withDefault = foo.applyOrElse(_: Int, (_: Int).toString)
或者,也许您想要这样的东西:
implicit class PartialFunToFun[A,B](val f: PartialFunction[A,B]) extends AnyVal {
def withDefault(bar: A => B) = f.applyOrElse[A,B](_: A, bar)
}
并使用它:foo.withDefault(_.toString)(1)
此外,如果您只想获取另一个PartialFunction
您可以使用下一个语法:
val withDefault = foo.orElse[Int, String]{case x => x.toString}
您在前两个中遇到的错误并非特定于orElse
。当您尝试单独定义相同的函数时,也会发生它们。
scala> { _.toString }
<console>:12: error: missing parameter type for expanded function ((x$1: <error>) => x$1.toString)
{ _.toString }
scala> { case x: Int => x.toString }
<console>:12: error: missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: ?
{ case x: Int => x.toString }
^
对于最后一个,您定义了一个函数而不是一个 PartFunction,从而导致"类型不匹配",因为orElse
期望传递 PartFunction。
scala> { (x: Int) => x.toString }
res3: Int => String = $$Lambda$1127/2044272973@3d5790ea
我要补充的最后一件事是,orElse
旨在将两个 Partial 函数联合起来。 _.toString
本身不是 PartFunction,尽管您可以创建一个使用它的 PartialFunction。对我来说,听起来您希望为所有未定义foo的值提供一个"默认"结果,因此我认为您实际上想要applyOrElse
因为这是它的用例。请参阅 API 以了解更多信息。