Scala选项 - 摆脱if(opt.isDefined){}

lau*_*cer 27 scala scala-option

我的代码变得乱七八糟,使用以下代码模式:

val opt = somethingReturningAnOpt
if (opt.isDefinedAt) {
    val actualThingIWant = opt.get
}
Run Code Online (Sandbox Code Playgroud)

有没有办法简化这个?(似乎不必要的复杂和代码味道).理想情况下它会是这样的:

if (Some(actualThingIWant) = somethingReturningAnOpt) {
   doSomethingWith(actualThingIWant)
}
Run Code Online (Sandbox Code Playgroud)

有可能吗?

Rog*_*ach 34

也许是这样的:

somethingReturningAnOpt match {
  case Some(actualThingIWant) => doSomethingWith(actualThingIWant)
  case None =>
}
Run Code Online (Sandbox Code Playgroud)

或者作为pst建议:

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

// or...

for (actualThingIWant <- somethingReturningAnOpt) {
  doSomethingWith(actualThingIWant)
}
Run Code Online (Sandbox Code Playgroud)


Dun*_*gor 30

选项争论的规范指南是托尼莫里斯.

  • 我个人认为大多数情况下案件陈述更清楚; 我不确定为什么Tony会劝阻他们. (2认同)

Wil*_*ger 10

要么:

somethingReturningAnOpt.map(doSomethingWith(_))
Run Code Online (Sandbox Code Playgroud)

如在:

val str = Some("foo")
str.map(_.toUpperCase)
Run Code Online (Sandbox Code Playgroud)

...并且flatMap当结果doSomethingWith是选项本身时使用.

val index = Option(Map("foo" -> "bar"))
index.flatMap(_.get("whatever"))        // Returns None :-)
index.map(_.get("whatever"))            // Returns Some(None) :-(
Run Code Online (Sandbox Code Playgroud)

  • 你甚至可以将它缩短为`somethingReturningAnOpt.map(doSomethingWith)`,不是吗? (2认同)

zig*_*tar 5

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

val opt = somethingReturningAnOpt
if (opt.isDefinedAt) {
    val actualThingIWant = opt.get
}
Run Code Online (Sandbox Code Playgroud)

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

val thingIWant = opt.getOrElse(myDefaultValue)
Run Code Online (Sandbox Code Playgroud)

或者,如果你不想拥有它actualThingIWant的主体if,这意味着只有在定义了选项时你想要触发一些副作用,你可以写:

opt.foreach{ thingIWant => 
  println(thingIWant)
}
Run Code Online (Sandbox Code Playgroud)

或者更短一些

opt.foreach(println)
Run Code Online (Sandbox Code Playgroud)