2016-06-19 17 views
0

Ich frage mich „durch Löschen beseitigt“ zu erhalten, wenn es möglich ist, ein Tupel innerhalb Schauspieler zu empfangen, ohne diese Warnung zu empfangen:Ist es möglich, ein Tupel innerhalb Schauspieler ohne Warnung

non-variable type argument Long in type pattern (Long, Int) is unchecked since it is eliminated by erasure 

obwohl der Code scheint gültig zu sein und funktioniert:

override def receive: Receive = { 
    case tuple: (Long, DateTime) => sendPlace(tuple._1, tuple._2) 
} 

Fehle ich etwas?

Antwort

3

Schreiben

case (id: Long, time: DateTime) => sendPlace(id, time) 

wird auch unkontrolliert Abgüsse vermeiden, aber Łukasz ist richtig: Sie sollten eine Fallklasse für diesen Zweck definieren.

seit zwei Anwendungen kommunizieren miteinander erlaubt es mir nicht zwei Mal der Fall Klasse

Natürlich definieren Sie es zweimal nicht definieren sollte. Definieren Sie es einmal in einer Bibliothek, von der beide Anwendungen abhängen. Auf diese Weise 1) machen Sie deutlich, wo Anwendungen kommunizieren; 2) Wenn Sie den Nachrichtentyp ändern müssen (z. B. ein anderes Feld hinzufügen oder den Typ eines der Felder ändern), werden Sie viel weniger wahrscheinlich vergessen, eine der Seiten zu ändern.

Können Sie bitte einfach erklären, warum ich diese Warnung nicht erhalte, wenn sie nicht im Zusammenhang mit einem Akteur steht, der eine Nachricht erhält?

Sie tun:

val x: Any = ("a", "b") 

x match { 
    case tuple: (Long, DateTime) => 
    println("shouldn't match, but does") 
} 
2

Tupel sind generische Typen, z.B. Tuple2[T1, T2] und in der JVM sind diese Typparameter gelöscht und nicht in der Laufzeit vorhanden. Es gibt eine Menge zu diesem Thema online.

Ihr Code funktioniert, aber nur die Sache, die überprüft wird, um zu sehen, ob Nachricht mit dem Muster übereinstimmt, ist, wenn die Nachricht Tuple2 ist, nicht inner seine Typen. Wenn dieser Aktor einen anderen Tuple2 bekommt, sagen wir (String, String), erhalten Sie eine Klassenausnahme beim Versuch, String in Long zu konvertieren, wenn Sie versuchen, das erste Element an die Methode sendPlace zu übergeben.

Zum Beispiel in folgenden

override def receive: Receive = { 
    case tuple: (Long, DateTime) => sendPlace(tuple._1, tuple._2) 
    case tuple: (Int, Int) => sender ! (tuple._1 + tuple._2) 
} 

zweite Muster nicht erreichbar ist, wird es nie übereinstimmen, wie jeder Tuple2 auf das erste Muster und throw Ausnahme übereinstimmen, wenn der Typ nicht stimmt.

Im Allgemeinen sollten Sie Fallklassen für Nachrichten erstellen. Dies hat den Vorteil eines aussagekräftigen Namens sowohl für die Nachricht als auch für ihre Mitglieder, Tupel sagt nichts weiter als seine Typen. Sie sollten die Nachrichten definieren, die der Akteur in seinem Begleitobjekt verarbeiten kann.

object BookingActor { 
    case class BookingRequest(placeId: Long, bookingTime: DateTime) 
} 

class BookingActor { 
    import BookingActor._ 

    override def receive: Receive = { 
    case BookingRequest(id, time) => bookPlace(id, time) 
    } 

    // ... 
} 
+0

Gute Antwort danke, bitte, dass in der realen Code beachten Sie die Namen aussagekräftiger sind, und ich denke, dass es genug verständlich ist und seit zwei Anwendungen kommunizieren miteinander erlaubt es mir nicht, um die Case-Klasse zweimal zu definieren, würde ich lieber ein Tupel verwenden. Kannst du bitte, bitte, erklären, warum ich diese Warnung nicht bekomme, wenn sie nicht im Kontext eines Schauspielers steht, der eine Nachricht erhält?Ersetzt die JVM das Tupel durch eine Fallklasse? – Simon