【问题标题】:How does Scala's apply() method magic work?Scala 的 apply() 方法是如何工作的?
【发布时间】:2009-08-03 18:18:53
【问题描述】:

在 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 似乎强烈倾向于一致地应用一组较小的规则,而不是包含许多例外的许多规则。这最初对我来说似乎是个例外。

【问题讨论】:

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


【解决方案1】:

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

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

【讨论】:

  • 我会添加“当f 是一个对象(包括函数)”。当f是方法时,显然没有这样的翻译。
  • @AlexeyRomanov:好吧,如果f 是一个没有参数列表定义的方法,那么f(a) 确实被解释为类似于val _tmp = f; _tmp.apply(a)。但这确实进入了头发分裂的领域。
【解决方案2】:

实际上是相反的,一个对象或类有一个apply方法是正常的情况,一个函数是用apply方法隐式构造一个同名对象的方法。实际上,您定义的每个函数都是 Functionn 特征的子对象(n 是参数的数量)。

有关该主题的更多信息,请参阅Scala Language Specification6.6:功能应用程序部分。

【讨论】:

  • +1 用于更改 Scala 语言规范。由于您的页码已过时,我添加了正确的位置。
【解决方案3】:

我之所以这么问,是因为 Scala 似乎强烈支持一致地应用一组较小的规则,而不是包含许多例外的许多规则。

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

【讨论】:

    猜你喜欢
    • 2016-04-20
    • 2015-12-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多