Scala - “if(true) Some(1)” without having to type

2020-08-17 06:06发布

问题:

In scala, if you have an Option, you can get another Option by doing oldOption.map(_.something). What I want to do is take a boolean and do the same thing. In other words, I want shorthand for the following:

if(someCondition)
  Some(data)
else
  None

Is there an idiomatic way to get an Option out of a Boolean like this without having to do "else None"?

回答1:

Scalaz has this. The code would look like this:

import scalaz._
import Scalaz._
val b = true  
val opt = b option "foo"

The type of opt will be Option[String]



回答2:

If you don't mind creating the data every time,

Some(data).filter(someCondition)

will do the trick. If you do mind creating the data every time,

Option(someCondition).filter(_ == true).map(_ => data)

but I don't think that's any clearer. I'd go with if-else if I were you.

Or you could

def onlyIf[A](p: Boolean)(a: => A) = if (p) Some(a) else None

and then

onlyIf(someCondition){ data }


回答3:

How about playing with the fire:

implicit class CondOpt[T](x: => T) {
  def someIf(cond: Boolean) = if (cond) Some(x) else None
}

Use:

data someIf someCondition

Drawbacks:

  1. Dangerous, implicit conversion from Any
  2. Calculates data every time


回答4:

import PartialFunction._
condOpt(someCondition) {
  case true => data
}

Personally I use this pattern a lot when I need to extract something, e.g.

val maybeInt: Option[Int] = condOpt(string) {
  case AsInt(i) if i > 0 => i
}


回答5:

Scala 2.13 has Option.when(someCondition)(dataExpression) and its corollary Option.unless

https://github.com/scala/scala/commit/44d08f68eb88c83a803eda240b6fdb18450aa8af



回答6:

in Scala 2.13 you could use Option.when()

Option.when(true)(data)

or you could use the opposite of it, which is Option.unless()

Option.unless(false)(data)


标签: scala