Quelle est la différence entre `::` et`+: "pour les ajoutant à une liste)?
List
a 2 méthodes qui sont spécifiés pour ajouter un élément à un (immuable) liste:
+:
(mise en place deSeq.+:
), et::
(définie uniquement dansList
)
+:
techniquement a un type plus général de la signature—
def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[List[A], B, That]): That
def ::[B >: A](x: B): List[B]
—mais en ignorant l'implicite, qui d'après la doc message exige simplement That
être List[B]
, les signatures sont équivalentes.
Quelle est la différence entre List.+:
et List.::
? Si ils sont en fait identiques, je suppose +:
serait préférable de ne pas dépendre de la mise en œuvre concrète List
. Mais pourquoi une autre définition de la méthode, et quand le client le code de l'appeler?
Modifier
Il est aussi un extracteur pour ::
dans la correspondance de modèle, mais je me demandais à propos de ces méthodes particulières.
Voir aussi: Scala liste de concaténation, ::: vs ++
Vous devez vous connecter pour publier un commentaire.
La meilleure façon de déterminer la différence entre les deux méthodes est de regarder le code source.
La source de
::
:La source de
+:
:Comme vous pouvez le voir, pour
List
, les deux méthodes ne sont une seule et même (le compilateur choisira Liste.canBuildFrom pour laCanBuildFrom
argument).Donc, la méthode à utiliser? Normalement choisir l'interface (
+:
) que la mise en œuvre (::
), mais parce queList
est un général de la structure de données dans les langages fonctionnels, il a ses propres méthodes, qui sont largement utilisés. De nombreux algorithmes de construire de la façon deList
œuvres. Par exemple, vous trouverez un grand nombre de méthodes qui ajoute des éléments uniques àList
ou appelez la pratiquehead
outail
méthodes parce que toutes ces opérations sontO(1)
. Par conséquent, si vous travaillez en local avec unList
(à l'intérieur d'une seule des méthodes ou classes), il n'y a pas de problème pour choisir leList
de méthodes spécifiques. Mais si vous voulez communiquer entre les classes, c'est à dire que vous voulez écrire des interfaces, vous devez choisir le plus généralSeq
interface.List.::
publiquement? On dirait qu'ils pourraient avoir mis en œuvre tout enList.+:
, de remplacer l'appel à::
dans la premièrecase
avecnew scala.collection.immutable.::(elem, this)
.List
et non pas sur un généralSeq
pour les raisons déjà expliquées par sschaef. Aussi, selon cette table il y a d'énormes différences sur la façon dont chaqueSeq
mise en œuvre est destinée à être utilisée. Par exemple+:
effectuera terriblement sur unQueue
et à l'aide de::
vous protège contre accidentellement de le transmettre à votre algorithme.::
. Un autre point souvent évoqué, c'est que l'existence de::
a des raisons historiques. Les premières versions de la Scala n'ont pas généralisée des collections que nous avons aujourd'hui. En outre, laML
de la famille des langages fonctionnels ont:
que la Liste ajoutant de l'opérateur. Par conséquent, son origine est beaucoup plus profonde qu'elle en a l'apparence.+:
est plus générique, car il permet le type de résultat sera différent du type de l'objet auquel il est appelé. Par exemple: