¿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 Listespecí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+:Listlugar deSeq, también podría utilizarListmé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 ::: zes más rápido quex ++ y ++ z, porque:::es correcto asociativo.x ::: y ::: zse 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 dosLists. Con++usted puede agregar cualquier colecciónList, lo cual es terrible:++También es fácil de mezclar con+:fuente
x ::: y ::: zdebe reemplazarlo porList(x, y, z).flatten. pastebin.com/gkx7Hpadxyy(znunca 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)iterayy agregaz, luego iteraxy agrega el resultado dey ::: z.xyyambos se repiten una vez.(x ::: y) ::: ziteraxy agregay, luego itera el resultado dex ::: yy agregaz.ytodavía se repite una vez, peroxse 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