2010-08-16 89 views
13

如果Scala的功能是我怎麼進程返回要麼

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

應該是什麼處理返回的結果的正確方法? val a = A() 和?

+0

你也可以使用Try [ArrayBuffer [Int]],它有內置的Exception部分。在這種情況下,你必須模式匹配:http://www.scala-lang.org/files/archive/nightly/docs/library/index .html#scala.util.Try – Jaap 2013-11-27 18:15:22

回答

14

的最簡單的方法是使用模式匹配

val a = A() 

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

另外,還有各種在任相當簡單的方法,它可用於該作業。這裏的scaladoc http://www.scala-lang.org/api/current/index.html#scala.Either

3

一種方法是

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

將實際評估的用於表達的機構只有一個。

+0

好吧,這是有效的,但在我看來,這是以一種醜陋的方式濫用「for」。如果你看到一個'for',你期望一個循環,但是在這裏它被用作一種'if'語句。模式匹配(請參閱Dave Griffith的答案)更清晰,更易於理解。 – Jesper 2010-08-17 14:16:36

+2

嗯,這取決於。在Scala中,表達式比循環具有更廣泛的語義。基本上所有具有map/flatmap的東西都可以用於。這是方便的,即在選項的情況下。 – michid 2010-08-17 16:16:01

32

我通常更喜歡使用fold。您可以使用它像地圖:

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) 

或者你可以使用它像一個模式匹配:

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

或者你可以使用它像getOrElseOption

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

我應該提到,如果你只想使用它來映射右側,那麼'a.right.map(_。length)'就不那麼簡單了,而是做了你想要的。通常,'.right'和'.left'方法使'Either'的工作方式非常類似,除了像'Option'這樣的其他情況下保留'None',它保留了'Either' '是。同樣,'a.right.getOrElse'比'fold'更簡單。我喜歡'fold'就是你可以一次完成所有這些事情並將它們結合起來。 – 2010-08-16 20:59:56

+0

使用right.map的問題是你不能逃避到左邊(例如,將一些Right值放入左邊,例如,如果它們是錯誤的話)。 – 2016-01-25 18:59:30