¿Hay alguna diferencia entre :::
y ++
para concatenar listas en Scala?
scala> List(1,2,3) ++ List(4,5)
res0: List[Int] = List(1, 2, 3, 4, 5)
scala> List(1,2,3) ::: List(4,5)
res1: List[Int] = List(1, 2, 3, 4, 5)
scala> res0 == res1
res2: Boolean = true
De la documentación parece que ++
es más general, mientras que :::
es List
específico. ¿Se proporciona este último porque se usa en otros lenguajes funcionales?
list
scala
concatenation
Luigi Plinge
fuente
fuente
:::
es un operador de prefijo como todos los métodos que comienzan con:
Respuestas:
Legado. La lista se definió originalmente para tener un aspecto funcional de idiomas:
Por supuesto, Scala desarrolló otras colecciones, de manera ad-hoc. Cuando salieron 2,8, las colecciones han sido rediseñados para una máxima reutilización de código y API consistente, por lo que se puede utilizar
++
para concatenar los dos colecciones - e incluso los iteradores. List, sin embargo, debe mantener sus operadores originales, aparte de uno o dos que quedaron en desuso.fuente
:::
a favor de++
ahora? También usar en+:
lugar de::
?::
es útil debido a la coincidencia de patrones (ver el segundo ejemplo de Daniel). No se puede hacer eso con+:
List
lugar deSeq
, también podría utilizarList
métodos idiomáticos . Por otro lado, hará que sea más difícil cambiar a otro tipo, si alguna vez desea hacerlo.::
y:::
) como operaciones más generales que son comunes a otras colecciones. No descartaría ninguna operación del lenguaje.:+
y+:
extractores de objetos.Siempre uso
:::
. Hay dos razones: eficiencia y seguridad de tipo.Eficiencia
x ::: y ::: z
es más rápido quex ++ y ++ z
, porque:::
es correcto asociativo.x ::: y ::: z
se analiza comox ::: (y ::: z)
, que es algorítmicamente más rápido que(x ::: y) ::: z
(este último requiere O (| x |) más pasos).Tipo de seguridad
Con
:::
usted solo puede concatenar dosList
s. Con++
usted puede agregar cualquier colecciónList
, lo cual es terrible:++
También es fácil de mezclar con+
:fuente
x ::: y ::: z
debe reemplazarlo porList(x, y, z).flatten
. pastebin.com/gkx7Hpadx
yy
(z
nunca se repite en ningún caso, por lo que no tiene ningún efecto en el tiempo de ejecución, es por eso que es mejor agregar una lista larga a una corta que al revés) pero La complejidad asintótica no cuenta toda la historia.x ::: (y ::: z)
iteray
y agregaz
, luego iterax
y agrega el resultado dey ::: z
.x
yy
ambos se repiten una vez.(x ::: y) ::: z
iterax
y agregay
, luego itera el resultado dex ::: y
y agregaz
.y
todavía se repite una vez, perox
se repite dos veces en este caso.:::
funciona solo con listas, mientras que++
se puede usar con cualquier tragable. En la implementación actual (2.9.0),++
cae de nuevo sobre:::
si el argumento es también unaList
.fuente
Un punto diferente es que la primera oración se analiza como:
Mientras que el segundo ejemplo se analiza como:
Entonces, si está utilizando macros, debe tener cuidado.
Además,
++
para dos listas se llama:::
pero con más sobrecarga porque se pide un valor implícito para tener un generador de Lista a Lista. Pero los microbenchmarks no probaron nada útil en ese sentido, supongo que el compilador optimiza tales llamadas.Micro-puntos de referencia después del calentamiento.
Como dijo Daniel C. Sobrai, puede agregar el contenido de cualquier colección a una lista usando
++
, mientras que con:::
solo puede concatenar listas.fuente