2012-03-13 20 views
5

En Scala puede definir parámetros que descienden de otro que toma el primero como parámetro. Por ejemplo, en Lift puede encontrar tales cosas en Record y MapperRepetición de los parámetros del tipo de Scala

MongoMetaRecord[BaseRecord <: MongoRecord[BaseRecord]] 

¿Qué significa eso y cómo es eso útil?

+3

Tenga en cuenta que lo mismo es posible y realmente hecho en Java o C#. por ejemplo, SortedStructure > ', SortedStructure donde T: IComparable '. –

Respuesta

9

Este es un patrón que se utiliza a menudo para que una clase abstracta sepa el tipo de la clase real de hormigón que lo extiende. A veces es útil saber cuál es el tipo concreto final: por ejemplo, usarlo como el tipo de devolución de un método que produce una copia del objeto actual.

Supongamos que quiere hacer esto: deje que una clase abstracta Abstract conozca el tipo concreto que lo implementa. Se podría empezar por definir un parámetro de tipo, tal como esto:

trait Abstract[A] { 
    def copyObject: A = ... 
} 

Pero luego te das cuenta de que en realidad, A debe ser una subclase de Abstract en sí, ya que no quiere subclases para proporcionar una parametrización al azar. Por lo que podría añadir lo siguiente:

trait Abstract[A <: Abstract] 

... pero pronto se dará cuenta de que Abstract se ha convertido en un tipo genérico, así, por lo que más bien necesita esto:

trait Abstract[A <: Abstract[A]] 

Como paso final, es probable que quieren hacer A covariante si es posible, con el fin de permitir que las clases abstractas intermedios a lo largo de la ruta de herencia de Abstract a la clase final de hormigón:

trait Abstract[+A <: Abstract[A]] 
class Concrete1 extends Abstract[Concrete1] 

trait RefinedAbstract[+A <: RefinedAbstract[A]] extends Abstract[A] 
class Concrete2 extends RefinedAbstract[Concrete2] 

Esto significa que cada tipo no hoja (abstracto) debe parametrizarse, y que solo la clase concreta final podrá soltar el parámetro tipo.

Cuestiones relacionadas