2010-08-16 6 views
13

se una funzione Scala ècome faccio a processo tornato O

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

quello che dovrebbe essere il modo giusto per elaborare il risultato restituito? val a = A() e?

+0

È inoltre possibile usa una Prova [ArrayBuffer [Int]], questa ha la parte Eccezione incorporata. In tal caso devi concordare la corrispondenza: http://www.scala-lang.org/files/archive/nightly/docs/library/index .html # scala.util.Try – Jaap

risposta

14

Il modo più semplice è con pattern matching

val a = A() 

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

alternativa, ci una varietà di metodi abbastanza semplici sono accese, che possono essere utilizzati per il lavoro. Ecco lo scaladoc http://www.scala-lang.org/api/current/index.html#scala.Either

3

Un modo è

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

Solo uno dei corpi dei a manifestare effettivamente essere valutati.

+0

Ok, funziona, ma secondo me questo è un uso scorretto di 'for' in un modo brutto. Se vedi un 'for', ti aspetti un ciclo, ma qui è usato come una sorta di istruzione' if'. La corrispondenza dei pattern (vedi risposta di Dave Griffith) è molto più pulita e più facile da capire. – Jesper

+2

Beh, dipende. In Scala le espressioni hanno una semantica più ampia del looping. Fondamentalmente tutto ciò che ha map/flatmap può essere usato con for. Questo è conveniente, ad esempio nel caso di Option. – michid

32

Generalmente preferisco usare fold. Si può usare come mappa:

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) 

Oppure si può utilizzare come un pattern match:

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

In alternativa si può utilizzare come getOrElse in Option:

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

Devo dire che se si usa _ solo _ per mappare il lato destro, 'a.right.map (_. Length)' sta scrivendo meno e fa quello che vuoi. Generalmente, i metodi '.right' e' .left' rendono 'Either' molto simile all'opzione, eccetto invece di preservare' None', mentre l'altro caso come 'Option' fa, mantiene qualunque sia il lato opposto di' 'è. Allo stesso modo, 'a.right.getOrElse' è più semplice di' fold'. Quello che mi piace di 'fold' è che puoi fare tutte queste cose contemporaneamente e combinarle. –

+0

Il problema con l'utilizzo di right.map è che non è possibile eseguire l'escape a sinistra (ad esempio, apportare alcuni valori Right a sinistra, ad esempio se si tratta di un errore). –

Problemi correlati