2011-01-05 18 views
20

Al mirar el scaladoc para Traversable y TraversableLike, estoy teniendo dificultades para averiguar cuál es la diferencia entre ellos (excepto que uno se extiende al otro). La única diferencia aparente en la documentación es que dice que Traversable es un "rasgo" y TraversableLike es un "rasgo de plantilla". Pero buscar en Google "rasgo de plantilla" no revela una definición para este término. ¡Ayuda!¿Cuál es la diferencia entre un "rasgo" y un "rasgo de plantilla"?

Respuesta

21

No he visto esta terminología de uso general en Scala, y creo que es específica para el diseño de la API de colecciones de Scala. Puede obtener más información leyendo The Architecture of Scala Collections (especialmente la sección sobre "factorizar operaciones comunes") [1] y the Scala collections SID. El §4.2 del SID es relevante, aunque se mencionan como "rasgos de implementación" allí:

Las clases de colección como Traversable o Vector heredan todas sus implementaciones concretas desde un rasgo de implementación. Estos rasgos se nombran con el sufijo Like like; por ejemplo VectorLike es el rasgo de implementación para Vector y TraversableLike es el rasgo de implementación para Traversable.

En resumen, su propósito es a la vez a la aplicación por separado para su uso fuera de la jerarquía de colecciones (por ejemplo StringOps extiende TraversableLike pero no Traversable) y al factor a cabo operaciones comunes de tal manera que el tipo de colección se conserva (ver IttayD's answer para una explicación más completa).

Debo notar que realmente no necesita preocuparse por estas clases a menos que esté ampliando la jerarquía de colecciones. Para uso ordinario, concéntrese en los rasgos Traversable, Iterable, Seq, etc. Si eres nuevo en la API de Scala Collections, te sugiero que comiences con Scala 2.8 Collection API document, luego haz referencia al scaladoc según sea necesario. No se puede esperar que la "gran imagen" mire a través del scaladoc.

[1] crédito va a michid para este enlace

+2

¡Gracias por su excelente respuesta! Sin embargo, la última frase me entristeció un poco: "no se puede esperar que la 'gran imagen' mire por el scaladoc" - qué desafortunado ... Siento que en el caso de la biblioteca estándar de Java (al menos para los paquetes "centrales" java.lang, java.util, etc. que han existido desde 1.1) que pude obtener la imagen completa mirando a través del javadoc. – Adam

22

Los rasgos XXXLike tienen un papel importante de añadir el parámetro genérico Repr. Los métodos que se supone que devuelven el mismo tipo de colección, como filter, map, flatMap, se implementan en rasgos de nivel bajo (TraversableLike). Para codificar el tipo de retorno, esos rasgos que reciben:

trait TraversableLike[+A, +Repr] ... 
    ... 
    def filter(p: A => Boolean): Repr = { 

(para el mapa y flatMap el asunto es más complicado, no voy a entrar en ello aquí)

Ahora supongamos que tiene un nuevo tipo de colección. Se podría hacer:

trait MyCollection[+A] extends TraversableLike[A, MyCollection] 

Pero entonces, si alguien quiere ampliar su colección, que están atrapados con valores de retorno de MiColeccion de los diversos métodos heredados.

Así que en lugar, se crea:

trait MyCollectionLike[+A, +Repr] extends TraversableLike[A, Repr] 

y

trait MyCollection[+A] extends MyCollectionLike[A, MyCollection] 

y cualquier persona que quiera ampliar su colección se extiende MyCollectionLike

+0

IttayD, esta debería ser la Pregunta frecuente n. ° 1 en el sitio web de Scala. Hay al menos tres formas diferentes de llevar a cabo este truco de "devolver tipos de este método es lo mismo que la clase heredante": saber cuál se usó para la biblioteca de colecciones Scala (y que es, por lo tanto, probablemente el mecanismo preferido) es algo se deben mostrar más principiantes de Scala. – Adam

1

El [...] Al igual que las clases son clases de implementación para las clases de colección reales.En cierto sentido, actúan como implementaciones de plantillas, de las cuales la mayoría de las conductas, si no todas, heredan el comportamiento.

Para obtener una visión general muy detallada y accesible, lea The Architecture of Scala Collections.

Cuestiones relacionadas