【发布时间】:2013-05-01 21:46:47
【问题描述】:
在scala中,如果你有一个Option,你可以通过oldOption.map(_.something)得到另一个Option。我想做的是取一个布尔值并做同样的事情。换句话说,我想要以下内容的简写:
if(someCondition)
Some(data)
else
None
有没有一种惯用的方法可以像这样从布尔值中获取选项,而不必执行“else None”?
【问题讨论】:
标签: scala
在scala中,如果你有一个Option,你可以通过oldOption.map(_.something)得到另一个Option。我想做的是取一个布尔值并做同样的事情。换句话说,我想要以下内容的简写:
if(someCondition)
Some(data)
else
None
有没有一种惯用的方法可以像这样从布尔值中获取选项,而不必执行“else None”?
【问题讨论】:
标签: scala
如果您不介意每次都创建数据,
Some(data).filter(someCondition)
会成功的。如果您介意每次都创建数据,
Option(someCondition).filter(_ == true).map(_ => data)
但我不认为这更清楚。如果我是你,我会选择 if-else。
或者你可以
def onlyIf[A](p: Boolean)(a: => A) = if (p) Some(a) else None
然后
onlyIf(someCondition){ data }
【讨论】:
Option(someCondition).filter(identity).map(_ => data)
onlyIf 方法,但我希望它可以添加到scala.lang 中的新Some 对象中。然后你可以做Some.onlyIf(x % 2 == 0)(x) 来返回一个Option[Int]。不过,这真的只有在 Some 中的东西相当复杂时才有用,我可以看到 Some.onlyIf(cond) { // lots of code here }} 这样做。
implicit class SomeOnlyIf(val some: Some.type) extends AnyVal { def onlyIf[A](p: Boolean)(a: => A) = if (p) Some(a) else None }
Scalaz 有这个。代码如下所示:
import scalaz._
import Scalaz._
val b = true
val opt = b option "foo"
opt 的类型将是 Option[String]
【讨论】:
玩火怎么样:
implicit class CondOpt[T](x: => T) {
def someIf(cond: Boolean) = if (cond) Some(x) else None
}
用途:
data someIf someCondition
缺点:
Any 的危险隐式转换
【讨论】:
implicit class CondOpt[T](x: => T)
import PartialFunction._
condOpt(someCondition) {
case true => data
}
当我需要提取某些东西时,我个人经常使用这种模式,例如
val maybeInt: Option[Int] = condOpt(string) {
case AsInt(i) if i > 0 => i
}
【讨论】:
Scala 2.13 具有 Option.when(someCondition)(dataExpression) 及其推论 Option.unless
https://github.com/scala/scala/commit/44d08f68eb88c83a803eda240b6fdb18450aa8af
【讨论】:
在 Scala 2.13 中,您可以使用 Option.when()
Option.when(true)(data)
或者你可以使用它的反义词,即Option.unless()
Option.unless(false)(data)
【讨论】: