将 PartialFunction 与常规函数组合
Combine a PartialFunction with a regular function
所以,假设,我想为 PartialFunction
:
提供 "catch all" 回退
val foo: PartialFunction[Int, String] = { case 1 => "foo" }
val withDefault = foo orElse { _.toString }
这不编译:missing parameter type for expanded function ((x) => x.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 到 string 的部分函数传递到它期望接收从 in 到 string 的部分函数的地方。这一点都没有歧义,我为什么要这样做?
也许你需要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: <error>) => x.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 }
^
对于最后一个,您定义的是函数而不是 PartialFunction,因此导致 "type mismatch",因为 orElse
期望传递 PartialFunction。
scala> { (x: Int) => x.toString }
res3: Int => String = $$Lambda27/2044272973@3d5790ea
我要补充的最后一件事是 orElse
是联合两个 PartialFunction 的一种方式。 _.toString
本身不是 PartialFunction,但您可以创建一个使用它的 PartialFunction。对我来说,这听起来像是您想为 foo 未定义的所有值获得 "default" 结果,所以我认为您实际上想要 applyOrElse
而不是因为这是它的用例。 See the API to learn more.
所以,假设,我想为 PartialFunction
:
val foo: PartialFunction[Int, String] = { case 1 => "foo" }
val withDefault = foo orElse { _.toString }
这不编译:missing parameter type for expanded function ((x) => x.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 到 string 的部分函数传递到它期望接收从 in 到 string 的部分函数的地方。这一点都没有歧义,我为什么要这样做?
也许你需要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: <error>) => x.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 }
^
对于最后一个,您定义的是函数而不是 PartialFunction,因此导致 "type mismatch",因为 orElse
期望传递 PartialFunction。
scala> { (x: Int) => x.toString }
res3: Int => String = $$Lambda27/2044272973@3d5790ea
我要补充的最后一件事是 orElse
是联合两个 PartialFunction 的一种方式。 _.toString
本身不是 PartialFunction,但您可以创建一个使用它的 PartialFunction。对我来说,这听起来像是您想为 foo 未定义的所有值获得 "default" 结果,所以我认为您实际上想要 applyOrElse
而不是因为这是它的用例。 See the API to learn more.