I am new to Scala. I have question about List class. This is an abstract and sealed class. It means cannot be instantiated, neither extended. So what is its usage? How can it be that something like following works?
val myList = List(1,2,3)
Would myList be a reference to the List object isntance? Also, if productElement is an abstract method how can that be implemented?
thanks.
Regarding:
val myList = List(1,2,3)
When the compiler encounters an expression which creates a class instance without the new
modifier, it looks up that classes companion object to look for a .apply
method. In the case of list, it is defined as:
override def apply[A](xs: A*): List[A] = xs.toList
Thus, this compiles successfully. You can view this when asking the compiler to emit type information after the typer phase:
def main(args: Array[String]): Unit = {
val l: List[Int] = scala.collection.immutable.List.apply[Int](1, 2, 3);
()
}
Would myList be a reference to the List object isntance?
The run-time type of myList
would be either a cons (::
) or the empty list (Nil
).
if productElement is an abstract method how can that be implemented?
This is a compiler trick. productElement
and productArity
(and more) are both generated at compile time for any case class definition. For example, given the following case class:
case class Bar(i: Int)
The compiler generates:
// an incomplete view of the generated case class methods and fields
// omitted for brevity.
case class Bar extends AnyRef with Product with Serializable {
<caseaccessor> <paramaccessor> private[this] val i: Int = _;
<stable> <caseaccessor> <accessor> <paramaccessor> def i: Int = Bar.this.i;
def <init>(i: Int): yuval.tests.Foo.Bar = {
Bar.super.<init>();
()
};
<synthetic> def copy(i: Int = i): yuval.tests.Foo.Bar = new Bar(i);
<synthetic> def copy$default$1: Int = Bar.this.i;
override <synthetic> def productPrefix: String = "Bar";
// this is the relevant part to your question
<synthetic> def productArity: Int = 1;
<synthetic> def productElement(x$1: Int): Any = x$1 match {
case 0 => Bar.this.i
case _ => throw new IndexOutOfBoundsException(x$1.toString())
};
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments