在 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 似乎强烈支持一致应用较小的一组规则,而不是带有许多例外的许多规则。 最初这对我来说似乎是一个例外。
In Scala, if I define a method called apply
in a class or a top-level object, that method will be called whenever I append a pair a parentheses to an instance of that class, and put the appropriate arguments for apply()
in between them. For example:
class Foo(x: Int) {
def apply(y: Int) = {
x*x + y*y
}
}
val f = new Foo(3)
f(4) // returns 25
So basically, object(args)
is just syntactic sugar for object.apply(args)
.
How does Scala do this conversion?
Is there a globally defined implicit conversion going on here, similar to the implicit type conversions in the Predef object (but different in kind)? Or is it some deeper magic? I ask because it seems like Scala strongly favors consistent application of a smaller set of rules, rather than many rules with many exceptions. This initially seems like an exception to me.
发布评论
评论(3)
我认为没有比您最初所说的更深入的事情了:这只是编译器将
f(a)
转换为f.apply(a)
的语法糖作为特殊的语法情况。这可能看起来像是一个特定的规则,但其中只有少数(例如,使用
update
)允许 DSL 式的构造和库。I don't think there's anything deeper going on than what you have originally said: it's just syntactic sugar whereby the compiler converts
f(a)
intof.apply(a)
as a special syntax case.This might seem like a specific rule, but only a few of these (for example, with
update
) allows for DSL-like constructs and libraries.实际上是相反的,具有 apply 方法的对象或类是正常情况,而函数是使用 apply 方法隐式构造同名对象的方法。 实际上,您定义的每个函数都是 Functionn 特征的子对象(n 是参数的数量)。
请参阅 6.6: 函数应用 部分="nofollow noreferrer">Scala 语言规范 了解该主题的更多信息。
It is actually the other way around, an object or class with an apply method is the normal case and a function is way to construct implicitly an object of the same name with an apply method. Actually every function you define is an subobject of the Functionn trait (n is the number of arguments).
Refer to section 6.6:Function Applications of the Scala Language Specification for more information of the topic.
是的。 这条规则属于这个较小的集合。
Yes. And this rule belongs to this smaller set.