2010-08-16 3 views
13

si une fonction scala estcomment puis-je traiter soit retourné

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

ce qui devrait être la bonne façon de traiter le résultat retourné? val a = A() et?

+0

Vous pouvez également utilisez un Try [ArrayBuffer [Int]], la partie Exception est intégrée. Dans ce cas, vous devez faire correspondre: http://www.scala-lang.org/files/archive/nightly/docs/library/index .html # scala.util.Try – Jaap

Répondre

14

La meilleure façon est avec motif correspondant à

val a = A() 

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

Sinon, il y a une variété de méthodes assez simples sur un ou l'autre, qui peuvent être utilisés pour le travail. Voici le scaladoc http://www.scala-lang.org/api/current/index.html#scala.Either

3

Une façon est

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

Un seul des corps des expressions seront effectivement pour évaluer.

+0

D'accord, cela fonctionne, mais à mon avis c'est abuser de «pour» d'une manière laide. Si vous voyez un 'for', vous attendez une boucle, mais ici elle est utilisée comme une sorte d'instruction' if'. La correspondance des motifs (voir la réponse de Dave Griffith) est beaucoup plus propre et plus facile à comprendre. – Jesper

+2

Eh bien ça dépend. En Scala pour les expressions ont une sémantique plus large que la boucle. Fondamentalement, tout ce qui a carte/flatmap peut être utilisé avec. Ceci est pratique, c'est-à-dire dans le cas d'Option. – michid

32

Je préfère généralement utiliser fold. Vous pouvez l'utiliser comme carte:

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) 

Ou vous pouvez l'utiliser comme un match de modèle:

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

Ou vous pouvez l'utiliser comme getOrElse dans Option:

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

Je devrais mentionner que si vous ne voulez l'utiliser que pour mapper le côté droit, 'a.right.map (_. Length)' est moins typé et fait ce que vous voulez. Généralement, les méthodes '.right' et' .left' font que 'Either' fonctionne beaucoup comme une option, sauf qu'au lieu de conserver' None' comme le fait l'option 'Option', elle préserve le côté opposé de' 'Sither' 'est. De même, 'a.right.getOrElse' est plus simple que' fold'. Ce que j'aime dans «fold», c'est que vous pouvez faire toutes ces choses à la fois et les combiner. –

+0

Le problème avec l'utilisation de right.map est que vous ne pouvez pas vous échapper dans left (par exemple, faites des valeurs Right dans Left, par exemple s'il s'agit d'une erreur). –