2014-02-21 55 views
11

在Scala中處理Option我應該考慮什麼來決定是映射還是匹配匹配?舉例來說,如果我有Option[MyClass],我可以對付它通過以下方式:Scala選項:map vs模式匹配

def getList(myOptionInstance: Option[MyClass]): List[String] = 
    myOptionInstance map (...) getOrElse(List.empty[String]) 

def getList(myOptionInstance: Option[MyClass]): List[String] = myOptionInstance match { 
    case Some(mySomeInstance) => ..... 
    case None => List.empty[String] 
} 

我什麼時候會選擇一個比其他?

+6

在情況l因此,我更喜歡模式匹配,因爲它通常更容易理解,並且生成效率更高的代碼(不包含'Function1's)。 –

+2

其他選項:'myOptionInstance.toList flatMap(...)' – senia

回答

24

我第二@rarry:fold是處理這個的首選方式。

有些人喜歡模式匹配,因爲它很「酷」(不管它的意思),有時更易於閱讀。

我儘量避免使用getOrElse因爲它不強迫你使用相同類型的默認值類型裹在你的Option

def getOrElse[B >: A](default: ⇒ B): B 

所以你可以這樣寫:

val v = Some(42).getOrElse("FortyTwo") 

這裏v有類型Any。這樣一個愚蠢的例子很容易看出問題,但有時它不是那麼明顯,可能導致問題。

雖然fold

def fold[B](ifEmpty: ⇒ B)(f: (A) ⇒ B): B 

它迫使你返回兩個分支類型相同。

scala> Some(42).fold("fortyTwo")(v => v) 
<console>:8: error: type mismatch; 
found : Int 
required: String 
       Some(42).fold("fortyTwo")(v => v) 
+0

出於某種原因,這個選項甚至沒有想到我,感謝您指出關於'fold'''&''之間''類型檢查非常重要的區別'getOrElse'''。 – Prasanna

+0

Option.fold只在Scala 2.10中添加,所以很多人還沒有意識到它已經存在。感謝您指出它,以及有關使用getOrElse返回類型的重大警告。 – Steve

+0

順便提一句:'x => x'已經在名字'identity'下的'Predef'中定義了。 –

1

我會去這樣的:

myOptionInstance.fold(Nil: List[String])(...)