2014-02-21 52 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])(...)