class MyAdder(x: Int) {
def apply(y: Int) = x + y
}
val adder = new MyAdder(2)
val result = adder(4) // equivalent to x.apply(4)
它经常在伴侣对象中使用,为类或特征提供一个很好的工厂方法,这是一个例子:
trait A {
val x: Int
def myComplexStrategy: Int
}
object A {
def apply(x: Int): A = new MyA(x)
private class MyA(val x: Int) extends A {
val myComplexStrategy = 42
}
}
// we will be able to use this object as a function, as well as an object
object Foo {
var y = 5
def apply (x: Int) = x + y
}
Foo (1) // using Foo object in function notation
List(1,2,3) // same as List.apply(1,2,3) but less clutter, functional notation
// the way the factory method invocation would have looked
// in other languages with OO notation - needless clutter
List.instanceOf(1,2,3)
所以 apply 方法只是缩小Scala中函数和对象之间差距的一种方便方法 .
5
对于那些想要快速阅读的人来说,这是一个小例子
object ApplyExample01 extends App {
class Greeter1(var message: String) {
println("A greeter-1 is being instantiated with message " + message)
}
class Greeter2 {
def apply(message: String) = {
println("A greeter-2 is being instantiated with message " + message)
}
}
val g1: Greeter1 = new Greeter1("hello")
val g2: Greeter2 = new Greeter2()
g2("world")
}
3 回答
它来自于您经常想要将某些东西应用于对象的想法 . 更准确的例子是工厂之一 . 如果您有工厂,则需要将参数应用于它以创建对象 .
Scala家伙认为,因为它在很多情况下都会发生,所以有一个快捷方式可以调用
apply
. 因此,当您直接向对象提供参数时,它就像将这些参数传递给该对象的apply函数一样:它经常在伴侣对象中使用,为类或特征提供一个很好的工厂方法,这是一个例子:
从scala标准库中,您可能会看到如何实现
scala.collection.Seq
:Seq
是一个特征,因此new Seq(1, 2)
将无法编译,但是由于伴随对象和apply,您可以调用Seq(1, 2)
并且伴随对象选择实现 .数学家有他们自己的小搞笑方式,所以不要说“然后我们称函数
f
将x
作为参数" as we programmers would say, they talk about "将函数f
应用于其参数x
” .apply
用于缩小Scala中面向对象和功能范例之间的差距 . Scala中的每个函数都可以表示为一个对象 . 每个函数也有一个OO类型:例如,一个带有Int
参数并返回Int
的函数将具有Function1[Int,Int]
的OO类型 .由于Scala中的所有内容都是对象
f
现在可以将其视为对Function1[Int,Int]
对象的引用 . 例如,我们可以调用从Any
继承的toString
方法,这对于纯函数来说是不可能的,因为函数没有方法:或者我们可以通过在
f
上调用compose
方法并将两个不同的函数链接在一起来定义另一个Function1[Int,Int]
对象:现在,如果我们想要实际执行该函数,或者如数学家所说"apply a function to its arguments",我们将在
Function1[Int,Int]
对象上调用apply
方法:每次要执行表示为对象的函数时写入
f.apply(args)
都是面向对象的方式,但是会在不添加太多额外信息的情况下为代码添加很多混乱,并且能够使用更多标准符号会很好,例如f(args)
. 这就是Scala编译器的步骤,每当我们有一个函数对象的引用f
并写入f (args)
以将参数应用于所表示的函数时,编译器会静默地将f (args)
扩展为对象方法调用f.apply (args)
.Scala中的每个函数都可以被视为一个对象,它也可以用于其他方式 - 只要它具有
apply
方法,每个对象都可以被视为一个函数 . 这些对象可以在函数表示法中使用:当我们想要将对象视为函数时,有许多用例 . 最常见的情况是factory pattern . 我们可以使用工厂方法对代码添加混乱,而不是使用一组参数来创建关联类的新实例:
所以
apply
方法只是缩小Scala中函数和对象之间差距的一种方便方法 .对于那些想要快速阅读的人来说,这是一个小例子