How does this work in Scala?
val something = List(1,2,3)
List
is abstract, and you can't construct it by invoking new List()
, but List(1,2,3)
works just fine.
Because it is a call to the apply
method of the list companion object. In scala, a method called apply can be called with the method name ommitted (i.e. just with parens). It is by this mechanism that sequence and Map access works
Hence, List(1, 2, 3)
is in fact:
List.apply(1, 2, 3)
So this is then a call to the apply method of List's companion object, the implementation of which is:
override def apply[A](xs: A*): List[A] = xs.toList
So you can see that apply
is a method which takes a repeating parameter (a sequence), and calls the toList
method on this sequence. This toList on Seq is inherited from TraversableOnce
:
def toList: List[A] = new ListBuffer[A] ++= seq toList
So you can see that this creates a list via a ListBuffer
and the ++=
method:
override def ++=(xs: TraversableOnce[A]): this.type =
if (xs eq this) ++= (this take size) else super.++=(xs)
This ultimately gets its implementation of ++=
from Growable
:
def ++=(xs: TraversableOnce[A]): this.type = { xs.seq foreach += ; this }
Invoking new List()
does not work because List is a trait
(and a sealed
one at that) - you would have had to apply implementations for the abstract methods. The fact that it is sealed means that it can only be implemented by a class in the same source file.
List(1,2,3)
is "magic syntax" to call the apply
method in the companion object of trait or class List
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With