Home > database >  scala: Any default apply method in a class?
scala: Any default apply method in a class?

Time:09-04

Does scala provide a default apply method for a class?

I have a class:

class Player(tea: String, sal: Int = 0) {
    val team  = tea
    private val salary = sal
}

So no apply method here, and I haven't defined any companion object for it, so no apply method from there too.

But I am able to do:

val player = Player("AAAA", 1000)

With no 'new' operator used, I understand that this line of code must invoke some apply method. But there is none defined by me. So how does it work?

CodePudding user response:

Yes, since Scala 3, as described in the docs:

Scala case classes generate apply methods, so that values of case classes can be created using simple function application, without needing to write new.

Scala 3 generalizes this scheme to all concrete classes. Example:

class StringBuilder(s: String):
  def this() = this("")

StringBuilder("abc")  // old: new StringBuilder("abc")
StringBuilder()       // old: new StringBuilder()

This works since a companion object with two apply methods is generated together with the class. The object looks like this:

object StringBuilder:
  inline def apply(s: String): StringBuilder = new StringBuilder(s)
  inline def apply(): StringBuilder = new StringBuilder()

The synthetic object StringBuilder and its apply methods are called constructor proxies. Constructor proxies are generated even for Java classes and classes coming from Scala 2. The precise rules are as follows:

  1. A constructor proxy companion object object C is created for a concrete class C, provided the class does not have already a companion, and there is also no other value or method named C defined or inherited in the scope where C is defined.
  2. Constructor proxy apply methods are generated for a concrete class provided
    • the class has a companion object (which might have been generated in step 1), and
    • that companion object does not already define a member named apply.

Each generated apply method forwards to one constructor of the class. It has the same type and value parameters as the constructor.

  • Related