prm*_*rms 6 scala partialfunction
val even: PartialFunction[Int, String] = PartialFunction[Int, String] {
case i if i % 2 == 0 => i + " is even"
}
val isEven: PartialFunction[Int, String] = {
case i if i % 2 == 0 => i + " is even"
}
val odd: PartialFunction[Int, String] = PartialFunction[Int, String] {
case x if x % 2 == 1 => x + " is odd"
}
val isOdd: PartialFunction[Int, String] = {
case x if x % 2 == 1 => x + " is odd"
}
val tot = even orElse odd
val tot2 = isEven orElse isOdd
println(tot(3))
println(tot2(3))
Run Code Online (Sandbox Code Playgroud)
在此代码tot函数中抛出匹配错误,而tot2函数按预期工作.它们之间的区别仅在于它们的定义方式.任何人都能解释为什么这样的结果差异?
提前致谢!!!
核心区别在于,部分函数上的isDefinedAt未按照您在使用PartialFunction.apply方法的版本上所期望的那样定义.这就是为什么现在不推荐使用这个方法的原因,PartialFunction.apply意味着将一个总函数转换为一个部分函数,isDefinedAt总是返回true,这意味着它会认为它在你的例子中定义为3,并尝试应用该函数而不是回到你提供的偶数功能作为替代.
这在社区中引起了关于总功能与部分功能的共同痛点.PartialFunction是Function的一个子类型,我想在OO设计意义上它是一个带有附加方法(isDefinedAt)的函数,它告诉你函数是否为特定值定义.许多人认为这是一个错误,因为在Liskov的意义,功能应该是PartialFunction的一个亚型,因为你可以使用一个函数的任何地方PartialFunction的预期,但如果你使用其中一个功能,预计将编译PartialFunction,则可能会失败在运行时.我的感觉是,因为Function可以被认为具有一个始终返回true的隐式isDefinedAt,这将允许您更正关系并使Function成为PartialFunction的子类型.这在PartialFunction.apply中处于领先地位,它期望一个完整的函数,并且由于这个期望定义了isDefinedAt总是返回true,但是它不能强制执行那个期望,所以如果你调用PartialFunction.apply(somePartialFunction),那么大多数都会发生坏事.程序员不会期望.
PartialFunction.apply Scaladoc
PartialFunction[Int, String]{...} is syntactic sugar for
PartialFunction[Int, String].apply({...})
Run Code Online (Sandbox Code Playgroud)
最小化:
val even: PartialFunction[Int, String] = PartialFunction[Int, String]{
case i if i % 2 == 0 => i + " is even"
}
val isEven: PartialFunction[Int, String] = {
case i if i % 2 == 0 => i + " is even"
}
println(even.isDefinedAt(3)) //true
println(isEven.isDefinedAt(3)) //false
Run Code Online (Sandbox Code Playgroud)
在前两种情况下,您正在调用 的apply伴生对象中的函数PartialFunction。我知道,这听起来似乎应该有效。但事实并非如此,因为PartialFunction.apply应该阅读PartialFunction.fromTotalFunction。
这是一个scala语言问题,如果我没记错的话(现在找不到票,稍后会看),这个apply函数将消失并被fromTotalFunctionScala 2.13中取代。
更新
我指的票是#6005
自Scala 2.12.5以来似乎PartialFunction.apply已被弃用。
| 归档时间: |
|
| 查看次数: |
270 次 |
| 最近记录: |