VectorBuilder
non è destinato a essere utilizzato direttamente. Se si desidera ottenere un costruttore per un Vector
, è sufficiente chiamare lo Vector.newBuilder[T]
, che restituisce un Builder[T, Vector[T]]
(con l'istanza sottostante è un VectorBuilder
).
Quindi, se si desidera che il costruttore di default che sarebbe stato utilizzato per creare un Seq
, avete solo bisogno di chiamare Seq.newBuilder
:
scala> Seq(1,2,3)
res0: Seq[Int] = List(1, 2, 3)
scala> Seq.newBuilder[Int]
res1: scala.collection.mutable.Builder[Int,Seq[Int]] = ListBuffer()
scala> Seq.newBuilder[Int].result
res2: Seq[Int] = List()
Quanto sopra dimostra che l'implementazione predefinita di Seq
è la lista, e, logicamente, il builder predefinito per un Seq
è in realtà un mutable.ListBuffer
.
ListBuffer
è più di un semplice List
costruttore, è per questo che è in collection.mutable
mentre VectorBuilder
non è un Buffer
, non può essere utilizzato per altro che costruire un Vector
. Questo è probabilmente il motivo per cui è definito localmente in Vector
. Non sono sicuro del motivo per cui non è private
, non riesco a vederlo referenziato in nessuna parte dell'API pubblica di Vector
stesso. Forse dovrebbe essere (privato).
Solo per riferimento, non c'è magia nascosta accadendo con CanBuildFrom
, quasi sempre va solo attraverso il newBuilder
sopra:
quando non si specifica il tipo di raccolta previsto, come in Seq(1,2).map(_+1)
, l'unico oggetto disponibile è CanBuildFrom
comes from l'oggetto associato a Seq
ed è di tipo CanBuildFrom[Seq[_], T, Seq[T]]
. Ciò significa che anche il risultato sarà uno Seq
.
Come la maggior parte degli oggetti da compagnia delle collezioni, il CanBuildFrom
esempio Seq
fornisce solo fa una cosa: chiamare Seq.newBuilder
(che è definito in GenTraversableFactory ...)
Ecco perché CanBuildFrom
per Vector
utilizza un VectorBuilder
.Ad esempio, in questo:
scala> Vector(1,2,3).map(_+1)
res12: scala.collection.immutable.Vector[Int] = Vector(2, 3, 4)
Il costruttore che è stato utilizzato è:
scala> implicitly[CanBuildFrom[Vector[Int], Int, Vector[Int]]].apply()
res13: scala.collection.mutable.Builder[Int,Vector[Int]] =
[email protected]
OK, c'è un metodo 'newBuilder', e c'è una differenza tra' Builder' e 'Buffer. Poiché c'è un'altra bella risposta, la lascerò aperta per un po 'di tempo; al momento non posso davvero dire quale sia il migliore, grazie per la tua visione. Ma hai sollevato un'altra domanda: perché 'Seq.newBuilder' non restituisce un' VectorBuilder'? Non restituisce nemmeno un 'Builder', ed è persino una collezione più sofisticata? Ma sembra un'altra domanda, quindi se sei d'accordo, preferirei postarne un altro. – Beryllium
Per me, sembra che tu stia suggerendo che le persone usano Seq.newBuilder, ma qualcuno lo fa? Se avessi avuto bisogno di costruire una mappa un po 'alla volta, penso che avrei usato un mutabile.Mappa e poi .toMappa, non MapBuilder. Raramente, userò CanBuildFrom in un caso speciale. Ma forse è questo il tuo punto, stai prendendo il punto di vista di qualcuno che si aggancia alle collezioni. –
Qualcuno stava chiedendo dei pattern MVx, e ho guardato il mio primo codice di scala e ho trovato la mia confusione di principianti sul costruttore: https://github.com/som-snytt/House-of-Mirrors-Fork/blob/act/src/ principale/Scala/hom/LightBox.scala # L356 Spero che tu lo trovi divertente come me. –