2010-08-16 10 views
13

si una función Scala es¿Cómo proceso de regresar cualquier

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

lo que debería ser el camino correcto para procesar el resultado devuelto? val a = A() y?

+0

También puede use un Try [ArrayBuffer [Int]], este tiene la parte Exception incorporada. En ese caso, debe coincidir con el patrón: http://www.scala-lang.org/files/archive/nightly/docs/library/index .html # scala.util.Try – Jaap

Respuesta

14

La manera más fácil es con el patrón de búsqueda de

val a = A() 

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

Alternativamente, hay una variedad de métodos bastante sencillas a ambos, que pueden ser utilizados para el trabajo. Aquí está la scaladoc http://www.scala-lang.org/api/current/index.html#scala.Either

3

Una forma es

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

Sólo uno de los cuerpos de los de expresiones realmente será evaluado.

+0

Ok, esto funciona, pero en mi opinión esto es un uso indebido de 'para' de una manera fea. Si ve un 'for', espera un bucle, pero aquí se usa como un tipo de instrucción 'if'. La coincidencia de patrones (ver respuesta de Dave Griffith) es mucho más clara y fácil de entender. – Jesper

+2

Bueno, eso depende. En Scala, las expresiones tienen una semántica más amplia que el bucle. Básicamente, todo lo que tiene mapa/mapa plano se puede usar con for. Esto es conveniente, por ejemplo, en el caso de la Opción. – michid

32

Generalmente prefiero usar fold. Se puede utilizar como un mapa:

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) 

O se puede usar como un ajuste de patrones:

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

O puede usarlo como getOrElse en Option:

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

Debo mencionar que si _lo único_ desea usar para asignar el lado derecho, 'a.right.map (_. Length)' tiene menos tipeo y hace lo que quiere. En general, los métodos '.right' y' .left' hacen que 'Oither' funcione como opción, excepto que en lugar de conservar 'None' como lo hace el otro caso como' Option', conserva el lado opuesto del 'Oither 'es. Del mismo modo, 'a.right.getOrElse' es más simple que' fold'. Lo que me gusta de 'fold 'es que puedes hacer todas estas cosas a la vez y combinarlas. –

+0

El problema con el uso de right.map es que no puede escapar hacia la izquierda (por ejemplo, convertir algunos valores correctos a la izquierda, por ejemplo, si son un error). –

Cuestiones relacionadas