繁体   English   中英

scala:匿名部分函数奇怪的语法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM