2010-08-16 5 views
13

wenn eine scala FunktionWie verarbeiten wir zurück Entweder

def A(): Either[Exception, ArrayBuffer[Int]] = { 
... 
} 

ist, was sollte den richtigen Weg sein, das zurückgegebene Ergebnis zu verarbeiten? val a = A() und?

+0

Sie können auch benutze einen Try [ArrayBuffer [Int]], dieser hat den eingebauten Exception-Part. In diesem Fall musst du ein Muster erstellen: http://www.scala-lang.org/files/archive/nightly/docs/library/index .html # scala.util.Try – Jaap

Antwort

14

Der einfachste Weg ist mit Muster

val a = A() 

a match{ 
    case Left(exception) => // do something with the exception 
    case Right(arrayBuffer) => // do something with the arrayBuffer 
} 

Alternativ gibt es eine Vielzahl von relativ einfach Methoden auf beide

Anpassung, die für den Auftrag verwendet werden kann. Hier ist die scaladoc http://www.scala-lang.org/api/current/index.html#scala.Either

3

Eine Möglichkeit ist

val a = A(); 
for (x <- a.left) { 
    println("left: " + x) 
} 
for (x <- a.right) { 
    println("right: " + x) 
} 

Nur eine der Leichen der für Ausdrücke tatsächlich ausgewertet werden.

+0

Ok, das funktioniert, aber meiner Meinung nach ist das ein "hässlicher" Missbrauch. Wenn Sie ein 'for' sehen, erwarten Sie eine Schleife, aber hier wird es als eine Art' if' Anweisung verwendet. Pattern Matching (siehe Antwort von Dave Griffith) ist viel sauberer und einfacher zu verstehen. – Jesper

+2

Nun, es kommt darauf an. In Scala für Ausdrücke haben breitere Semantik als Schleifen. Grundsätzlich kann alles mit map/flatmap verwendet werden. Dies ist praktisch, d. H. Im Fall von Option. – michid

32

Ich bevorzuge generell fold. Sie können es wie Karte verwenden:

scala> def a: Either[Exception,String] = Right("On") 

a.fold(l => Left(l), r => Right(r.length)) 
res0: Product with Either[Exception,Int] = Right(2) 

Oder Sie es wie ein Mustererkennung verwenden können:

scala> a.fold(l => { 
    | println("This was bad") 
    | }, r => { 
    | println("Hurray! " + r) 
    | }) 
Hurray! On 

Oder Sie können es getOrElse verwenden wie in Option:

scala> a.fold(l => "Default" , r => r) 
res2: String = On 
+2

Ich sollte erwähnen, dass, wenn Sie _only_ es verwenden möchten, um die rechte Seite zuzuordnen, 'a.right.map (_. Length)' weniger tippen und tun, was Sie wollen. Im Allgemeinen machen die '.right' und' .left' Methoden 'Entweder' sehr ähnlich wie die Option, außer, dass' None' beibehalten wird, da der andere Fall wie 'Option' ist, was auch immer die entgegengesetzte Seite des' Entweder'erhält 'ist. Ebenso ist 'a.right.getOrElse' einfacher als' fold'. Was ich an 'fold' mag, ist, dass Sie all diese Dinge gleichzeitig tun und kombinieren können. –

+0

Das Problem bei der Verwendung von right.map besteht darin, dass Sie nicht nach links ausweichen können (z. B. wenn Sie einige rechte Werte zu einer Linken machen, z. B. wenn es sich um einen Fehler handelt). –