假设这段代码:
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
。
但到底为什么不呢?
为什么 Scala 编译器没有将函数字面量转换为某种概念:
new (String, String) => String
请记住,Scala 编译为 JVM 字节码。 JVM 中不存在“概念性
new (String, String) => String
”这样的东西。只有对象和方法(至少在 Java 8 之前)。在 Java 语言中,你必须在 Guava 和 Apache Commons 中使用无聊的 Callable<T>
、Runnable
或各种 Function
抽象。没有办法解决这个问题。从这个角度来看,Scala 基本上通过在匿名 FunctionX[...]
类上添加语法糖来隐藏 Java 样板。
这也是为什么当你使用需要函数的方法时,Scala 编译器必须做这么多摆弄的原因之一(所谓的 eta 扩展)。