Question

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?

Was it helpful?

Solution

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)
}

OTHER TIPS

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)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top