Natürlich merke ich, dass alle Typen do einen gemeinsamen Vorfahren haben, aber was ich meine, ist dies:
In dynamisch typisierten Sprachen ist es üblich, gemischte Rückgabetypen zu verwenden. Ein häufiger Fall ist eine Funktion, die versucht, Daten aus einer Datenbank abzurufen, und dann entweder ein Objekt (initialisiert mit den gefundenen Daten) oder FALSE (falls keine Daten gefunden wurden) zurückgibt.
Ein kleiner Pseudocode, um ein solches Anti-Pattern zu demonstrieren:
%Vor%Wenn Daten für meine Objekt-ID gefunden werden, bekomme ich einen DB-Datensatz als Objekt zurück. Wenn nicht, erhalte ich einen booleschen Wert. Dann liegt es natürlich an mir, dem Kunden, mehrere mögliche Rückgabetypen zu behandeln.
Ist das die einzige Möglichkeit, dies in Scala zu erreichen, um einen gemeinsamen Vorfahren für alle möglichen Rückgabetypen zu finden und dies als Rückgabetyp in der Signatur zu deklarieren?
%Vor%Oder ist es möglich, mehrere mögliche Rückgabetypen zu kommentieren?
(Beachten Sie, dass ich nicht hoffe, ist es möglich, dies zu tun, da ich es vorziehen würde, dass Funktionsrückgabetypen so eindeutig wie möglich sind. Es würde mir eine Erleichterung sein zu lernen, dass die Sprache zweideutige Rückgabetypen verbietet, was mehr der Grund ist, warum ich frage.
Was Sie suchen, ist eine markierte Vereinigung , Variante , abweichende Aufzeichnung , diskriminierte Vereinigung , disjoint union oder sum type .
Kombiniert mit Produkttypen werden sie zu algebraischen Datentypen .
Scala hat keine direkte Unterstützung für algebraische Datentypen, aber es muss nicht, weil sie leicht durch Vererbung modelliert werden können. (Scala hat den Modifizierer sealed
, um geschlossene ADTs zu unterstützen.)
Wenn Sie in Ihrem Beispiel wissen, dass der Rückgabetyp entweder SomeType
oder SomeOtherType
ist, können Sie es wie folgt modellieren:
Wenn Sie nicht wissen, was die Rückgabetypen sind, nur dass es zwei davon gibt, können Sie sie ähnlich modellieren:
%Vor% Dies ist ein bekannter Datentyp namens Either
(weil er entweder ein A
oder ein B
enthält) und in der Scala-Standardbibliothek als scala.util.Either
vorhanden ist.
Aber in Ihrem speziellen Fall gibt es einen spezifischeren Typ namens Maybe
oder Option
, der die Idee kapselt, dass ein Wert existiert oder nicht. Es sieht ungefähr so aus:
Auch dies wird von Scala bereits als scala.Option
bereitgestellt.
Der Vorteil von Either
über Option
ist, dass Sie auch Informationen im Fehlerfall zurückgeben können, anstatt nur anzugeben, dass es keinen Wert gibt. Sie können auch sagen, warum es keine gibt Wert. (Per Konvention ist die linke Seite von Either
der Fehler, die rechte Seite ist der "nützliche" Wert.)
Der Vorteil von Option
ist, dass es eine Monade ist. (Hinweis: Sie können Either
zu einer Monade machen, indem Sie sie entweder nach links oder nach rechts vorbelasten.)
Ja, verwenden Sie Either
:
Oder, wenn der Fall ohne Ergebnisse keinen bestimmten Wert benötigt, verwenden Sie Option
:
Siehe Tony Morris ' Option-Spickzettel für eine Liste der gebräuchlichsten Methoden Sie können Option
aufrufen und wie sie zum Mustervergleich übersetzt werden.
Zwei weitere Alternativen sind Validation
von Scalaz und Try
, neu in Scala 2.10.
Für Validation
gibt es einige wirklich gute Antworten auf StackOverflow, zum Beispiel: Methode Parameter Validierung in Scala, mit Verständnis und Monaden .
Für Try
siehe diesen Blogbeitrag: Der Leitfaden des Neophyten zu Scala Teil 6: Fehlerbehandlung mit Try . Derselbe Autor hat gute Beiträge auf Option
und Either
.
Tags und Links scala