What happens when you create a Seq object with Seq(1,2,3)?

前端 未结 2 600
梦如初夏
梦如初夏 2021-01-19 09:50

What exactly happens when you evaluate expression: Seq(1,2,3)?

I am new to Scala and I am now a bit confused about various collection types. Seq is a tr

2条回答
  •  臣服心动
    2021-01-19 10:10

    Seq is the val of:

    package object scala {
    ...
      val Seq = scala.collection.Seq
    ...
    }
    

    it points to object scala.collection.Seq:

    /** $factoryInfo
     *  The current default implementation of a $Coll is a `List`.
     *  @define coll sequence
     *  @define Coll `Seq`
     */
    object Seq extends SeqFactory[Seq] {
      /** $genericCanBuildFromInfo */
      implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Seq[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
    
      def newBuilder[A]: Builder[A, Seq[A]] = immutable.Seq.newBuilder[A]
    }
    

    and when you do Seq(1,2,3) the apply() method is ivoked from scala.collection.generic.GenericCompanion abstract class:

    /** A template class for companion objects of "regular" collection classes
     *  represent an unconstrained higher-kinded type. Typically
     *  such classes inherit from trait `GenericTraversableTemplate`.
     *  @tparam  CC   The type constructor representing the collection class.
     *  @see [[scala.collection.generic.GenericTraversableTemplate]]
     *  @author Martin Odersky
     *  @since 2.8
     *  @define coll  collection
     *  @define Coll  `CC`
     */
    abstract class GenericCompanion[+CC[X] <: GenTraversable[X]] {
    ...
      /** Creates a $coll with the specified elements.
       *  @tparam A      the type of the ${coll}'s elements
       *  @param elems  the elements of the created $coll
       *  @return a new $coll with elements `elems`
       */
      def apply[A](elems: A*): CC[A] = {
        if (elems.isEmpty) empty[A]
        else {
          val b = newBuilder[A]
          b ++= elems
          b.result()
        }
      }
    }
    

    and finally, this method builds an object of Seq type by code mentioned above

    And most importantly what is the type of the returned value?

    object MainClass {
    
      def main(args: Array[String]): Unit = {
    
        val isList = Seq(1,2,3).isInstanceOf[List[Int]]
    
        println(isList)
      }
    }
    

    prints:

    true
    

    So, the type is scala.collection.immutable.List

    Also in REPL I see that the contents of the evaluated expression is actually a List(1,2,3), but the type is apparently Seq[Int].

    The default implementation of Seq is List by the code mentioned above.

    Why is not an Indexed collection type, like Vector? What is the logic behind all that?

    Because of immutable design. The list is immutable and to make it immutable and have a constant prepend operation but O(n) append operation cost and O(n) cost of accessing n'th element. The Vector has a constant efficient implementation of access and add elements by id, prepend and append operations.

    To have a better understanding of how the List is designed in Scala, see https://mauricio.github.io/2013/11/25/learning-scala-by-building-scala-lists.html

提交回复
热议问题