30

我的代码充斥着以下代码模式:

val opt = somethingReturningAnOpt
if (opt.isDefinedAt) {
    val actualThingIWant = opt.get
}

有什么方法可以简化这个吗?(这似乎是不必要的复杂和代码味道)。理想情况下,它会是这样的:

if (Some(actualThingIWant) = somethingReturningAnOpt) {
   doSomethingWith(actualThingIWant)
}

这样的事情可能吗?

4

4 回答 4

38

也许是这样的:

somethingReturningAnOpt match {
  case Some(actualThingIWant) => doSomethingWith(actualThingIWant)
  case None =>
}

或如 pst 建议的那样:

somethingReturningAnOpt.foreach { actualThingIWant =>
  doSomethingWith(actualThingIWant)
}

// or...

for (actualThingIWant <- somethingReturningAnOpt) {
  doSomethingWith(actualThingIWant)
}
于 2011-12-08T07:02:55.777 回答
33

期权争论的规范指南由托尼·莫里斯(Tony Morris)撰写。

于 2011-12-08T07:55:21.563 回答
10

或者:

somethingReturningAnOpt.map(doSomethingWith(_))

如:

val str = Some("foo")
str.map(_.toUpperCase)

...并flatMap在结果doSomethingWith是选项本身时使用。

val index = Option(Map("foo" -> "bar"))
index.flatMap(_.get("whatever"))        // Returns None :-)
index.map(_.get("whatever"))            // Returns Some(None) :-(
于 2011-12-08T07:17:21.983 回答
5

下面的代码不能做一些有用的事情,因为在if,之后actualThingIWant并不总是定义,因此只要您稍后尝试使用,这段代码就不会编译actualThingIWant

val opt = somethingReturningAnOpt
if (opt.isDefinedAt) {
    val actualThingIWant = opt.get
}

因此,您必须提供一个默认值。这可以通过以下方式实现getOrElse

val thingIWant = opt.getOrElse(myDefaultValue)

或者,如果您不想actualThingIWant在 的主体之后有if,这意味着您只想在定义选项时触发一些副作用,您可以编写:

opt.foreach{ thingIWant => 
  println(thingIWant)
}

或者更短一点

opt.foreach(println)
于 2011-12-08T09:17:58.590 回答