Seq
è il super-tratto, quindi è più generico, ha le caratteristiche comuni a tutte le sequenze, sia lineare che indicizzato.
Se vi state chiedendo che tipo di sequenza viene creato con il metodo Seq.apply
nell'oggetto compagna di Seq, possiamo avere uno sguardo alla realizzazione.
Tenete presente che se si utilizza Seq.apply, si sta implicando che basta un Seq e che il codice non si preoccupa se è lineare o indicizzate
Il tl; dr risposta è allora: si utilizza LinearSeq
o IndexedSeq
quando è necessario avere un certo caratteristiche di prestazioni, si utilizza il più generale Seq
quando non vi interessa circa la differenza
Questo è l'oggetto associato di Seq
:
object Seq extends SeqFactory[Seq] {
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Seq[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
def newBuilder[A]: Builder[A, Seq[A]] = immutable.Seq.newBuilder[A]
}
Il metodo newBuilder[A]
è quello che viene utilizzato per costruire il Seq, come si può verificare nel metodo Seq.apply (definito sul tratto GenericCompanion
):
def apply[A](elems: A*): CC[A] = {
if (elems.isEmpty) empty[A]
else {
val b = newBuilder[A]
b ++= elems
b.result()
}
}
Ora la domanda è: che cosa fa un immutable.Seq.newBuilder[A]
build? Andiamo a vedere, questa volta sull'oggetto immutable.Seq
compagna:
object Seq extends SeqFactory[Seq] {
// stuff
def newBuilder[A]: Builder[A, Seq[A]] = new mutable.ListBuffer
}
Si costruisce un mutabile ListBuffer
! Perché? Questo perché un mutable.ListBuffer
è anche un Builder[A, Seq[A]]
, ovvero una classe che viene utilizzata dalla raccolta di raccolte per creare nuove raccolte.
La collezione di uscita effettiva viene da questa linea (come potete vedere sopra):
b.result()
Allora, qual è il tipo di ritorno del ListBuffer.result()
? Andiamo a vedere in ListBuffer:
// Implementation of abstract method in Builder
def result: List[A] = toList
ecco qui: è una lista.
Seq(1,2,3)
restituisce un List[Int]
sotto il cofano, ma il punto qui è che se si sta utilizzando Seq(), non è necessario sapere che tipo di raccolta si ha perché si sta implicando che il più astratto l'interfaccia è sufficiente per le vostre esigenze
Solo per aggiungere: se usi IndexedSeq.apply (metodo factory), costruirà un vettore per te. Se usi Seq.apply o LinearSeq.apply, ti darà una lista. Poiché in molti casi è preferibile un vettore, è necessario utilizzare IndexedSeq.apply in caso di dubbio. – pumpump