3

抱歉,如果这是一个新手问题...在 Scala 中,我知道当您有一个返回实例但可能不返回任何内容的函数时,最好使用 anOption而不是返回。null我知道这在安全性方面会变得更好,因为您不会传递空引用,并且不会冒着风险NullPointerException

但是,有没有比使用模式匹配更简洁的方式来处理选项?我最终使用的语法如下:

val optObj : Option[MyObject] = myFunctionThatReturnsOption
optObj match {
  case Some(obj) => {
  //my code using obj
  }

  case None => _
}

实际上,所有这些都相当于 Java 版本:

MyObject obj = myMethodThatCanReturnNull()
if (obj != null) {
  //my code using obj
}

Option在使用而不是引用时,是否有其他方法可以避免 Scala 中的所有这些样板null文件?我想要做的就是执行一段代码,只要Option包含一些对象(即不是None)。

4

5 回答 5

8

使用foreach,getOrElse和/或map如果您想以更一致的方式工作。这是一些用例和我会做什么:

 //I want to get a non-null value and I have a sane default
 val result = myOption getOrElse 3

 //I want to perform some side effecting action but only if not None
 myOption foreach{ value =>
   println(value toString ())
 }
 //equivalently
 for(value <- myOption){
   //notice I haven't used the "yeild" keyword here
 }

 //I want to do a computation and I don't mind if it comes back as an Option
 val result = for(value <- myOption) yield func(value)
 val equivalent = myOption map func

第三个示例将map在这两种情况下使用。

当您可以在“理解”(谷歌术语)中混合和匹配事物时,它变得非常有趣。假设它func也返回一个Option但我只希望在特定情况下工作:

 val result = for{ 
   value <- myOption if value > 0
   output <- func(value)
 } yield output

现在我得到一个Option但仅当myOption包含一个大于零的整数时。很漂亮的东西,不是吗?

于 2014-04-23T14:43:11.397 回答
3

foreach如果您只想使用以下值执行一些副作用操作,则可以使用:

optObj.foreach(obj => {
    //my code using obj
})

如果您有其他用例,您应该在Optionlike或.上使用其他方法。mapfiltergetOrElse

于 2014-04-23T14:43:11.577 回答
1

这是有关选项的 Scala 最佳实践的一个很好的参考:http: //blog.tmorris.net/posts/scalaoption-cheat-sheet/index.html

于 2014-04-23T15:01:29.363 回答
1

当然,如果我只关心现值,我通常使用选项的方式是 foreach:

optObj.foreach { obj => 
 //...
}

话虽如此,还有很多其他选择(@wheaties 入伍了),有些人一直在为真正的选择而战。

于 2014-04-23T14:43:41.557 回答
1

您可以flatMap很好地使用 - 方法Option。喜欢他:

case class Player(name: String)
def lookupPlayer(id: Int): Option[Player] = {
  if (id == 1) Some(new Player("Sean"))
  else if(id == 2) Some(new Player("Greg"))
  else None
}
def lookupScore(player: Player): Option[Int] = {
  if (player.name == "Sean") Some(1000000) else None
}

println(lookupPlayer(1).map(lookupScore))  // Some(Some(1000000))
println(lookupPlayer(2).map(lookupScore))  // Some(None)
println(lookupPlayer(3).map(lookupScore))  // None

println(lookupPlayer(1).flatMap(lookupScore))  // Some(1000000)
println(lookupPlayer(2).flatMap(lookupScore))  // None
println(lookupPlayer(3).flatMap(lookupScore))  // None
于 2014-04-23T14:46:34.030 回答