这在Scala中如何运作?
val something = List(1,2,3)
List
是抽象的,您无法通过调用new List()
来构建它,但List(1,2,3)
可以正常工作。
答案 0 :(得分:16)
因为它是对列表伴随对象的apply
方法的调用。在scala中,可以使用省略的方法名称(即仅使用parens)调用名为 apply 的方法。通过这种机制,序列和地图访问工作
因此,List(1, 2, 3)
实际上是:
List.apply(1, 2, 3)
所以这是对List companion object的apply方法的调用,implementation of which是:
override def apply[A](xs: A*): List[A] = xs.toList
因此,您可以看到apply
是一个采用重复参数(序列)的方法,并在此序列上调用toList
方法。 Seq 上的 toList 继承自TraversableOnce
:
def toList: List[A] = new ListBuffer[A] ++= seq toList
因此,您可以看到这会通过ListBuffer
和++=
方法创建一个列表:
override def ++=(xs: TraversableOnce[A]): this.type =
if (xs eq this) ++= (this take size) else super.++=(xs)
这最终会从++=
Growable
的实施
def ++=(xs: TraversableOnce[A]): this.type = { xs.seq foreach += ; this }
调用new List()
不起作用,因为List是trait
(并且sealed
) - 您将不得不应用抽象方法的实现。它被密封的事实意味着它只能由同一源文件中的类实现。
答案 1 :(得分:11)
List(1,2,3)
是调用companion object特征或类apply
中的List
方法的“神奇语法”。