2016-12-24 3 views
8

Wenn wir also eine Methode ausführen, die sowohl einen Fehler liefert als auch einen Wert zurückgibt, können wir den Rückgabetyp unserer Methode als Either[SomeErrorType, ReturnType] codieren. Aber viele Male führen wir eine Methode für seine Nebenwirkungen aus, so dass der Rückgabetyp Unit ist.Welcher Rückgabetyp sollte eine Scala-Methode haben, wenn sie Fehler zurückgeben/zurückgeben kann, aber den Rückgabetyp Einheit hat?

Ich könnte natürlich eine Either[SomeErrorType, Unit] zurückgeben, aber das sieht auf jeden Fall seltsam aus.

Ich könnte auch nur ein Option[SomeErrorType] zurück, aber es sieht nicht wirklich viel besser (und bricht eine eventuell vorhandene Symmetrie mit anderen Either[SomeErrorType, NonUnitReturnType] s.

Was in diesen Fällen Ihr Ansatz ist?

  1. def m(): Unit // and implicitly know that exceptions can be thrown?;
  2. def m(): Either[SomeErrorType, Unit] // this is odd;
  3. def m(): Option[SomeErrorType] // this is odd, as it makes it look as the return type of m() on a successful run is an error code.
  4. Andere, an die ich nicht denken kann?

Dank

Antwort

10

Ich benutze Try[Unit] für diesen Fall.

Es codiert, dass das Ergebnis der Methode entweder erfolgreich ist oder mit einigen Exception fehlschlägt, die weiter verarbeitet werden können.

  • vs T => UnitTry Aufzüge Fehler zu der Anwendungsebene, die Codierung in der Signatur, die einige Fehler erwartet werden und ermöglicht die Anwendung als Wert zu handhaben.
  • vs. Option[T] => Option ist nur in der Lage zu kodieren, dass der Betrieb einen Wert hatte oder nicht
  • vs. Either[SomeErrorType, Unit] =>Try Es ist einfacher, mit der Verwendung von monadischen Konstruktionen zu arbeiten.

Ich habe so etwas verwendet, um Prüfungen zu implementieren. (Imaginärteil Beispiel)

for { 
    entity <- receiveEntity // Try[Entity] 
    _ <- isRelational(entity) 
    _ <- isComplete(entity) 
    _ <- isStable(entity) 
} yield entity 

wo jede Überprüfung der Form ist: Entity => Try[Unit]

Dies wird die entity zurück, wenn alle Überprüfungen des ersten Fehlers übergeben, die die Überprüfung fehlgeschlagen.

+0

Warum? Was sind die Vorteile gegenüber den anderen Ansätzen? Wie es aussieht, scheint es, dass es bestenfalls ein Kommentar sein sollte. –

+1

@TravisBrown Travis, du hast Recht. Ich habe die Antwort erweitert, um eine bessere Erklärung zu geben. Fröhliches Weihnachten! – maasg

+2

über Entweder um einfacher in monadischen Konstruktionen zu arbeiten, ist es erwähnenswert, dass seit Scala 2.12 jetzt ist es so einfach wie Try. –

2

Eine weitere Option, die noch nicht erwähnt wurde, ist Validated von cats. Alle bisher genannten Optionen (Try, Either, Option) sind Monaden, während Validated ein anwendungsbezogener Funktor ist. In der Praxis bedeutet dies, dass Sie Fehler von mehreren Methoden akkumulieren können, die Validated zurückgeben, und Sie können mehrere Validierungen parallel durchführen. Das mag für Sie nicht relevant sein, und das ist ein wenig orthogonal zur ursprünglichen Frage, aber ich denke, dass es in diesem Zusammenhang erwähnenswert ist.

Wie für die ursprüngliche Frage, mit Unit Rückgabetyp für eine Nebeneffekt-Funktion ist völlig in Ordnung. Die Tatsache, dass diese Funktion auch Fehler zurückgeben kann, sollte Ihnen nicht im Wege stehen, wenn Sie den Rückgabetyp "echt" (richtig, erfolgreich, usw.) definieren.Wenn ich also aus Ihren ursprünglichen Optionen auswählen würde, würde ich Either[Error, Unit] gehen. Es sieht definitiv nicht komisch aus, und wenn jemand irgendwelche Nachteile darin sieht, würde ich sie gerne kennenlernen.

Verwandte Themen