Ich bekomme sehr seltsames Verhalten (zumindest scheint es mir) mit der Methode orElse
, die für PartialFunction
Es scheint mir so:
%Vor%macht Sinn, aber das ist nicht so, wie es sich verhält, und ich habe große Schwierigkeiten zu verstehen, warum die Typenunterschriften darauf hindeuten, was ich oben dargelegt habe.
Hier ist eine Abschrift von dem was ich mit Scala 2.11.2:
beobachte %Vor% Beachten Sie den Rückgabetyp von val b
, der den Typ der PartialFunction nicht erweitert hat.
Aber das funktioniert auch nicht wie erwartet:
%Vor%Es gibt ein paar Dinge, die mit Ihrem Versuch nicht stimmen, aber lassen Sie uns zuerst eine funktionierende Implementierung sehen:
%Vor%Es gibt zwei Hauptfehler in Ihrem Code:
empty
eine "catch-all" -Funktion ist, die Nothing
zurückgibt
Wie nicht um es zu definieren:
%Vor% Wenn Sie sich die Definition von PartialFunction.apply
Sie sehen, dass es eine Teilfunktion für any x
definiert und die angegebene f
-Funktion darauf anwendet. Jetzt ist Ihr { case "hello" => println("bye") }
das Argument f
, so dass Sie ungefähr mit dem folgenden (eindeutig unerwarteten) PartialFunction
:
Wenn Sie also fragen, ob es definiert ist, wird immer true zurückgegeben, da es für any definiert ist:
%Vor% Aber wenn Sie versuchen, apply
it
Sie treffen das innere Spiel nicht.
Da orElse
entscheidet, ob das "else" abhängig vom Ergebnis von isDefined
aufgerufen werden soll, ist es offensichtlich, warum es fehlschlägt.
Direkt von den Dokumenten :
def empty[A, B]: PartialFunction[A, B]
Die Teilfunktion mit leerer Domain. Jeder Versuch, eine leere Teilfunktion aufzurufen, führt dazu, dass
scala.MatchError
exception ausgelöst wird.
Das PartialFunction
(naja, es ist nicht wirklich partiell), das du suchst, ist:
oder - nur um zu zeigen, dass wir aus unseren Fehlern lernen -
%Vor% PartialFunction.empty[A,B]
entspricht:
(Diese Typprüfung, weil Nothing
ein Untertyp von A
und B
ist.)
oder äquivalent:
%Vor%Dies kann nichts erreichen.
.orElse
kann so verstanden werden, dass Listen von case-Anweisungen von zwei PartialFunction
s einfach verkettet werden. Also, in Ihrem Fall bedeutet a.orElse(PartialFunction.empty[Any,Unit]
:
vereinfacht das:
%Vor%oder
%Vor% MatchError
ist daher offensichtlich.
Beachten Sie, dass die Dokumentation auch immer empty
erwähnt wirft MatchError
.
Von dem, was ich erraten kann, wollten Sie ein PartialFunction
, das immer übereinstimmt. Dafür gibt es keine benannte Methode in der Standardbibliothek, aber warum sollte es da sein? Sie können einfach
Sie verwenden die Methode PartialFunction
object apply, die so definiert ist:
Im Grunde nimmt es eine Funktionsform A
bis B
und wickelt es automatisch in eine case-Anweisung, das Problem ist, dass Sie auch den Fall übergeben und ich bin nicht 100% sicher, was dann passiert, können Sie Versuchen Sie, eine Funktion an die Anwendung zu übergeben, oder Sie können es einfach ausprobieren, ohne die Methode apply zu verwenden:
Sie können das Merkmal auch erweitern und apply
und isDefined
implementieren, wie gezeigt. hier .
Tags und Links scala read-eval-print-loop functional-programming partialfunction