[英]scala: anonymous partial function strange syntax
我遇到了与此类似的代码,并且它甚至可以编译也很惊讶:
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
的有效语法是一个case函数:
val halfSize: PartialFunction[String, Int] = {
case s if s.length % 2 == 0 => s.length / 2
}
第一个代码似乎更优化,因为它只调用一次length
。 但是即使在SLS中,我也找不到语法的解释。 这是scalac的未记录功能吗?
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
}
}
这些规则在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成员,该成员从函数文字中的模式匹配派生,每个案例的主体均替换为true,并且添加了默认值(如果未给出),其值为false。
所以在这种情况下,它最终以
def isDefinedAt(x: String) = x.length match {
case even if even % 2 == 0 => true
case _ => false
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.