2016-05-14 11 views
1

Angesichts der folgenden Scala 2.11 Code benötigt:scala - Wie vollständig eines Objekts Typ-Parameter zu ignorieren, wenn

class Partials { 
    class Aggregate 
    class AggregateId[T <: Aggregate] 
    class Event[T <: Aggregate] 

    type EventListener = PartialFunction[Event[_], Unit] 

    val listeners = mutable.Set[EventListener]() 

    def addListener(l: EventListener) { 
    listeners += l 
    } 

    def process(e: Event[_]): Unit = { 
    listeners.foreach(listener => if (listener.isDefinedAt(e)) listener.apply(e)) 
    } 

    addListener { 
    case x => println(x) 
    } 
} 

Dies wird von meinem eigentlichen Code vereinfacht, ein Ereignis-Verarbeitung, aber es zeigt das gleiche Problem. Ich habe Ereignisse, die sich auf ein Aggregat beziehen, und ich habe Listener, die mit diesen Ereignissen umgehen können. Die Listener sind PartialFunctions, sodass sie mit einigen Event-Subtypen umgehen können, aber nicht mit allen.

Wie aufgeführt, erhalte ich die folgende Fehlermeldung für den addListener Aufruf am Ende:

type arguments [_$1] do not conform to class Event's type parameter bounds [T <: Partials.this.Aggregate] 
    addListener { 

Wenn ich den Alias ​​EventListener Typ verändern zu

type EventListener = PartialFunction[Event[_ <: Aggregate], Unit] 

ich stattdessen die folgenden Fehlermeldungen erhalten im process Methode:

Error:(19, 60) type mismatch; 
found : Partials.this.Event[_$2] where type _$2 
required: Partials.this.Event[_ <: Partials.this.Aggregate] 
    listeners.foreach(listener => if (listener.isDefinedAt(e)) listener.apply(e)) 

Error:(19, 79) type mismatch; 
found : Partials.this.Event[_$2] where type _$2 
required: Partials.this.Event[_ <: Partials.this.Aggregate] 
    listeners.foreach(listener => if (listener.isDefinedAt(e)) listener.apply(e)) 

Im Moment verstehe ich nicht wirklich, was vor sich geht. Event benötigt seinen Typparameter für Dinge, die nichts damit zu tun haben, aber für die PartialFunctions, die mit Ereignissen umgehen sollen, möchte ich diesen Typparameter einfach ignorieren, was ich mit der [_] gemacht habe. Was mache ich falsch?

Antwort

4

Dies scheint zu funktionieren:

import scala.collection.mutable 

class Partials { 
    class Aggregate 
    class AggregateId[T <: Aggregate] 
    class Event[T <: Aggregate] 

    type EventListener = PartialFunction[Event[_ <: Aggregate], Unit] 

    val listeners = mutable.Set[EventListener]() 

    def addListener(l: EventListener) { 
    listeners += l 
    } 

    def process(e: Event[_ <: Aggregate]) { 
    listeners.foreach(listener => if (listener.isDefinedAt(e)) listener.apply(e)) 
    } 

    addListener { 
    case x => println(x) 
    } 
} 

Beachten Sie, wie process Methode definiert ist. Diese Fehlermeldungen haben Ihnen mitgeteilt, dass Sie bei der Definition des Typs listener als PartialFunction[Event[_ <: Aggregate], Unit] die Instanz Event[_ <: Aggregate] an die Methoden isDefinedAt und apply übergeben müssen.

+0

Vielen Dank, das macht Sinn für mich. Ich muss es mir angewöhnen, alle Typdeklarationen zu überprüfen, nicht nur, wo ich den Fehler sehe. –

Verwandte Themen