摘自stack overflow回答
对于数学家来说,他们不会像程序员说“传递x给形参调用函数f”,而是“应用函数f给他的实参x”
parameter和argument的区别
- parameter是指函数定义时的参数,argument指的是函数调用时的参数
- 简略描述为:parameter = 形参(formal parameter),argument = 实参(actual parameter)
- 在不很严格的情况下,现在二者可以混用,一般用argument,而parameter使用比较少
apply有助于消除面向对象和函数式编程的二义性。Scala中每一个函数都可以表现为一个对象。每一个函数都有Function*
类型特质:例如,一个函数获取一个Int型参数并返回Int型参数将会有Function1[Int,Int]
的类型特质
//定义一个函数
(x: Int) => x + 1
//将一个函数转化为对象给一个变量
val f = (x: Int) => x+1
因为Scala中一切都是对象。f
可以被当做是Function1[Int,Int]
对象的引用。例如,我们可以调用继承于Any
的toString
方法,这样就不是一个纯函数了,因为函数并没有这些方法
f.toString
或者我们可以调用f
的compose
方法来定义另一个Function1[Int,Int]
,将两个不同的函数串在一起
val f2 = f.compose((x: Int) => x-1)
现在我们想要使用这个函数,可以调用Function1[Int,Int]
的apply
方法
f2.apply(2)
每当你想要调用一个表现为对象的函数时,你会这样写:f.apply(args)
,这是面向对象的方式,但是会给代码增加一些没用的东西。我们可以使用一种更为标准简洁的方式书写:f(args)
。scala的编译器会帮助你在对一个函数对象引用f
以f(args)
的方式应用参数给这个函数时将其静态扩展为对象方法的调用f.apply(args)
scala中的每一个函数可以被当做对象,同时所有对象可以被当做函数,可以调用apply
方法
下面的对象可以被当做函数
//我们可以像使用函数一样使用下面的对象
object Foo{
var y = 5
def apply(x: Int) = x+y
}
Foo(1) //以函数的形式使用对象
当我们将对象看做函数时还有许多更有用的例子。最普遍的应用就是工厂模式。在不给代码增加冗余度的情况下,我们可以应用对象的apply
方法将其传递给一组参数来创建一个相关类型的新实例。
所以apply方法就是一种在scala里消除函数和对象二义性的简便方法(可以说是一种语法糖了)