Scala的apply()方法魔法是如何工作的?

时间:2009-08-03 18:18:53

标签: scala syntactic-sugar magic-methods companion-object

在Scala中,如果我在类或顶级对象中定义一个名为apply的方法,那么每当我将一个圆括号添加到该类的实例时,将调用该方法,并放入适当的它们之间的apply()的参数。例如:

class Foo(x: Int) {
    def apply(y: Int) = {
        x*x + y*y
    }
}

val f = new Foo(3)
f(4)   // returns 25

基本上,object(args)只是object.apply(args)的语法糖。

Scala如何进行此转换?

这里是否存在全局定义的隐式转换,类似于Predef对象中的隐式类型转换(但不同类型)?或者它是一些更深层次的魔法?我问,因为看起来Scala强烈赞成一套较小的规则的一致应用,而不是许多例外的许多规则。这对我来说似乎是个例外。

3 个答案:

答案 0 :(得分:65)

我认为没有比你最初说的更深入了:它只是语法糖,编译器将f(a)转换为f.apply(a)作为一种特殊的语法案例。

这似乎是一个特定的规则,但只有少数(例如,使用update)允许DSL - 类似构造和库。

答案 1 :(得分:20)

实际上反过来说,带有apply方法的对象或类是正常情况,而函数是使用apply方法隐式构造同名对象的方法。实际上,您定义的每个函数都是Function n 特征的子对象(n是参数个数)。

有关该主题的更多信息,请参阅Scala Language Specification第77页的 6.6:功能应用程序部分。

答案 2 :(得分:8)

  

我问,因为看起来Scala强烈赞成一套较小的规则的一致应用,而不是许多例外的许多规则。

是。而且这个规则属于这个较小的集合。