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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8427313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 03:44:03  来源:igfitidea点击:

Scala Option - Getting rid of if (opt.isDefined) {}

scalascala-option

提问by laurencer

My code is becoming littered with the following code pattern:

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

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

Is there some way to simplify this? (it seems needlessly complex and a code smell). Ideally it would be something like:

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

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

Is anything like that possible?

有可能吗?

回答by Rogach

Maybe something like this:

也许是这样的:

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

or as pst suggests:

或如pst建议的那样:

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

// or...

for (actualThingIWant <- somethingReturningAnOpt) {
  doSomethingWith(actualThingIWant)
}

回答by Duncan McGregor

The canonical guideto Option wrangling is by Tony Morris.

Option wrangling的规范指南是由 Tony Morris 编写的。

回答by Wilfred Springer

Or:

或者:

somethingReturningAnOpt.map(doSomethingWith(_))

As in in:

如:

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

... and use flatMapwhen the result of doSomethingWithis an Option itself.

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

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

回答by ziggystar

The following code cannot do something useful, since after the if, actualThingIWantis not always defined and as such this code will not compile, as long as you try to use actualThingIWantlater.

下面的代码不能做一些有用的东西,因为后ifactualThingIWant并不总是定义,因此该代码将无法编译,只要你尝试使用actualThingIWant更高版本。

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

So, you have to provide a default value. This can be achieved with getOrElse:

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

val thingIWant = opt.getOrElse(myDefaultValue)

Or if you don't want to have actualThingIWantafter the body of the if, which means you want to trigger some side-effects only if the option is defined, you can write:

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

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

or a bit shorter

或短一点

opt.foreach(println)