Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does List(1,2,3) work in Scala?

Tags:

list

scala

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.

like image 389
Illarion Kovalchuk Avatar asked Nov 28 '22 18:11

Illarion Kovalchuk


2 Answers

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.

like image 103
oxbow_lakes Avatar answered Dec 19 '22 10:12

oxbow_lakes


List(1,2,3) is "magic syntax" to call the apply method in the companion object of trait or class List.

like image 26
Jesper Avatar answered Dec 19 '22 11:12

Jesper