I have been seeing some classes using the apply method, but I do not understand its purpose really I think. Does each class by default have it, or is it just for case classes by default? The apply method allows us to use the () shortcut on the object itself to call method or access various attributes? Is that its purpose or use?
-
4Does this answer your question? [What is the apply function in Scala?](https://stackoverflow.com/questions/9737352/what-is-the-apply-function-in-scala) – Hüseyin Zengin Jun 15 '20 at 18:02
-
You need to provide a minimal code to reproduce the problem. See more details on how to post a question at this link: https://stackoverflow.com/help/minimal-reproducible-example – Usama Abdulrehman Jun 16 '20 at 01:08
2 Answers
apply()
is just a method like any other. It is never required. Its only trick is that it can be abbreviated away.
class C {def apply(str:String) = s"-->$str<--"}
val c = new C
c("blah")
//res0: String = -->blah<--

- 50,871
- 7
- 38
- 64
Just expanding on @jwvh's answer, case classes have a default apply()
method on a default companion object, but not (necessarily) on individual case class instances.
For example, say you have the following:
final case class Person(name: String)
then you can consider that Scala, under the hood, automatically creates a default companion object for you, with an apply()
method similar to the case class's constructor. If you could see that code, it might appear like this:
object Person {
def apply(name: String): Person = new Person(name)
}
This allows you to create instances of the case class without having to use a new
operator:
val bob = Person("Bob") // Equivalent to Person.apply("Bob")
However, there's no apply()
method on this particular case class instance. But you can always add one:
final case class Person(name: String) {
def apply(greeting: String): String= s"$greeting $name!"
}
You can use this as follows:
val fred = Person("Fred") // Same as Person.apply("Fred")
fred("Hi") // Same as fred.apply("Hi"), returns "Hi Fred!"
In general, as a rule of thumb, apply()
methods on object
s (including companion objects) are mostly used for factory methods (methods that create instances of classes, such as Person.apply()
above)
However, apply()
methods on classes are mostly used to lookup information held by that class, through an obvious reference. For example, map collections will use apply(key: K)
to retrieve the value associated with a particular key, an array collection will use apply(i: Int)
to retrieve the value at position i
, etc.
But at the end of the day, apply()
is just a function, and it can do whatever you want it to do. That said, try to use it only in situations where the use of a specific function name is redundant, and don't use it if it's not obvious what is happening.
For example: this might be a good use of apply (depending upon what other operations storage has):
class Storage(/* ... */) {
/** Retrieve named item of data.
*
* @param name Name of data requested.
*
* @return Data item corresponding to specified `name`, or exception otherwise.
*/
def apply(name: String): Data = //...
}
val storage = new Storage(/* ... */)
// ...
val myResults = storage("myResults")) // same as storage.apply("myResults")
But this might be a bad example.
class Crazy(/* ... */) {
var balance: Double= /* ... */
def apply(amount: Double): Unit = {
balance -= amount
}
}
val mystery = new Crazy(/* ... */)
mystery(50.0) // WTF is this doing?

- 8,139
- 2
- 24
- 46