2

假设这段代码:

  def main(args: Array[String]) {
    val func = (x: String, y :String) => x + ", " + y
    println(myFunc(func))
  }

  def myFunc(f: (String, String) => String) = {
    f("Hey","how are you?")
  }

此代码的第二行由编译器替换为:

val func = new Function2[String, String, String] {
             def apply(x: String, y: String): String = x + ", " + y
           } 

我可以推断出func这种情况下的类型也对应于(String, String) => String)类型,如myFunc签名所示;表示与 .Function2[String, String, String]相同的类型(String, String) => String

为什么不同的符号?为什么 Scala 编译器没有将函数字面量转换为某种概念性的:new ((String, String) => String)没有无聊的Function2[String, String, String]类型?或相反亦然。

一种解释是类名不能是多部分的:(T1, T2) => R. 但为什么不呢?

4

1 回答 1

6

为什么 Scala 编译器没有将函数文字转换为某种概念:new (String, String) => String

请记住,Scala 编译为 JVM 字节码。JVM中没有“概念”之类的东西。new (String, String) => String只有对象和方法(至少在 Java 8 之前)。Callable<T>在 Java 语言中,您必须使用无聊Runnable或 Guava 和 Apache Commons 中的各种Function抽象。没有其他办法了。从这个角度来看,Scala 基本上通过在匿名FunctionX[...]类上添加语法糖来隐藏 Java 样板。

这也是为什么 Scala 编译器在使用预期函数的方法(所谓的eta 扩展)时必须做这么多摆弄的原因之一。

于 2012-12-05T18:26:33.300 回答