type parameter implicitly classes scala contravariance

scala - parameter - Ejemplo de contravarianza.



scala self class (2)

Tiene sentido para mí también. Como regla general, un tipo parametrizado tipo Type[A] debe ser contravariante con respecto a su tipo de parámetro A cada vez que está destinado a aceptar instancias de A para hacer algo con ellos aceptándolos como parámetros .

Por ejemplo, el Comparator[T] tipo Java Comparator[T] , si se hubiera definido en Scala, habría sido contravariante: un Comparator[Any] debería ser un subtipo de Comparator[String] , ya que puede comparar todos los objetos un Comparator[String] Puede comparar, y más. El ejemplo más general son los tipos de argumentos de las clases de FunctionX , que son todas contravariantes.

Estoy pensando en el siguiente ejemplo para ilustrar por qué es útil la contravarianza.

Consideremos un marco de GUI con Widgets , Events y Event Listeners .

abstract class Event; class KeyEvent extends Event class MouseEvent extends Event trait EventListener[-E] { def listen(e:E) }

Deje que los Widgets definan los siguientes métodos:

def addKeyEventListener(listener:EventListener[KeyEvent]) def addMouseEventListener(listener:EventListener[MouseEvent])

Estos métodos solo aceptan escuchas de eventos "específicos", lo cual está bien. Sin embargo, me gustaría definir también a los oyentes de "fregadero de la cocina", que escuchan todos los eventos y pasan a los oyentes a los métodos de "agregar oyente" mencionados anteriormente.

Por ejemplo, me gustaría definir LogEventListener para registrar todos los eventos entrantes

class LogEventListener extends EventListener[Event] { def listen(e:Event) { log(event) } }

Dado que el rasgo EventListener es contravariante en Event , podemos pasar LogEventListener a todos los métodos de "agregar oyente" sin perder su seguridad de tipo.

Tiene sentido ?


Tiene sentido para mí, de todos modos. Y también es uno de los ejemplos más intuitivos que he visto: algo que escucha todos los eventos naturalmente escuchará eventos clave o eventos del mouse.