문제

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?

도움이 되었습니까?

해결책

Maybe something like this:

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

or as pst suggests:

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

// or...

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

다른 팁

The canonical guide to Option wrangling is by Tony Morris.

Or:

somethingReturningAnOpt.map(doSomethingWith(_))

As in in:

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

... and use flatMap when the result of doSomethingWith is an Option itself.

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

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

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

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

val thingIWant = opt.getOrElse(myDefaultValue)

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

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

or a bit shorter

opt.foreach(println)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top