我遇到了类似于此的代码,它甚至编译时感到惊讶:
scala> val halfSize: PartialFunction[String, Int] = _.length match {
case even if even % 2 == 0 => even / 2
}
halfSize: PartialFunction[String,Int] = <function1>
scala> List("x", "xx").collect(halfSize)
res1: List[Int] = List(1)
据我所知,定义PartialFunction
的有效语法是一个案例函数:
val halfSize: PartialFunction[String, Int] = {
case s if s.length % 2 == 0 => s.length / 2
}
第一个代码似乎更加优化,因为它只调用length
一次。但即使在SLS中,我也无法找到语法的解释。这是scalac的无证特征吗?
答案 0 :(得分:0)
val halfSize: PartialFunction[String, Int] = _.length match {
case even if even % 2 == 0 => even / 2
}
上述函数中的下划线(_
)只是一个简短的符号,表示函数的单个参数。因此,上面的代码片段只是
val halfSize: PartialFunction[String, Int] = { (x: String) => x.length match {
case even if even % 2 == 0 => even / 2
}
}
答案 1 :(得分:0)
规则在https://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#anonymous-functions中给出:
匿名函数的最终运行时值由期望的类型确定:
...
PartialFunction[T, U]
,如果函数文字的形状为x => x match { … }
在这种情况下,文字确实具有这样的形状,正如流氓的答案所解释的那样,因此 PartialFunction
被允许作为期望的类型。
(编辑:实际上,它没有,因为它匹配x.length
而不是x
。这看起来像一个小错误,但应该通过更改规范来修复。)
PartialFunction的值接收一个额外的isDefinedAt成员,该成员派生自函数文字中的模式匹配,每个case的正文被替换为true,并且添加了默认值(如果没有给出) )评估为假。
所以在这种情况下,最终会以
结束def isDefinedAt(x: String) = x.length match {
case even if even % 2 == 0 => true
case _ => false
}