【发布时间】:2013-01-17 15:47:36
【问题描述】:
鉴于以下情况:
val x = Some(Some(1))
获得 1(如果不存在则为 -1)的最干净的方法是什么?
我正在从数据库查询返回的元组创建一个对象实例。元组中的一个值看起来像这样,所以我想要一个简短的“单线”来获取值或将参数设置为 -1。
【问题讨论】:
鉴于以下情况:
val x = Some(Some(1))
获得 1(如果不存在则为 -1)的最干净的方法是什么?
我正在从数据库查询返回的元组创建一个对象实例。元组中的一个值看起来像这样,所以我想要一个简短的“单线”来获取值或将参数设置为 -1。
【问题讨论】:
x.flatten 是您正在寻找的。在这里它会给你Some(1)。
如果您真的想在“那个不存在”的情况下获得-1,只需执行x.flatten.getOrElse(-1):
scala> Some(Some(1)).flatten.getOrElse(-1)
res1: Int = 1
scala> Some(None).flatten.getOrElse(-1)
res2: Int = -1
scala> None.flatten.getOrElse(-1)
res3: Int = -1
【讨论】:
为了理解通常是使用这些嵌套结构的一种非常易读的方式:
val x = Some(Some(1))
val result = for {
firstLevel <- x
secondLevel <- firstLevel
} yield {
// We've got an int, now transform it!
(secondLevel * 100).toString
}
结果是一个 Option[String],只有当你有两个 Some(s) 时才会发生转换。
你也可以使用模式匹配:
val result2 = for {
Some(v) <- x
} yield {
// We've got a int, now transform it!
(v * 100).toString
}
【讨论】:
虽然不是“单行”,但您可以创建一个函数来提取值。如果您将其设为通用并传入默认值,它可能会非常方便。
scala> def fetchFromOptions[A](default: A)(x: Option[Option[A]]) = x match {
| case Some(Some(a)) => a
| case _ => default
| }
fetchFromOptions: [A](default: A)(x: Option[Option[A]])A
scala> fetchFromOptions(-1)(Some(Some(1)))
res0: Int = 1
scala> fetchFromOptions(-1)(Some(None))
res1: Int = -1
【讨论】:
这是我想出的:
scala> val x = Some(Some(1))
x: Some[Some[Int]] = Some(Some(1))
scala> val y = x.map(_.getOrElse(-1)).get
y: Int = 1
scala> val x = Some(None)
x: Some[None.type] = Some(None)
scala> val y = x.map(_.getOrElse(-1)).get
y: Int = -1
这仅适用于您的第一级 Some 不是 None
【讨论】:
如果你真的知道它的Some(Some(1)),那么你可以使用无可辩驳的模式匹配表示法:
scala> val ssi1 = Some(Some(1))
ssi1: Some[Some[Int]] = Some(Some(1))
scala> val Some(Some(i1)) = ssi1
i1: Int = 1
如果组合中可能存在任何None,那么您必须使用其他人建议的更加谨慎和详细的形式。
对于那些觉得这是一个奇怪的符号的人,可以把它想象成你在 case 中写的 match 构造或 PartialFunction 文字,以匹配 Some(Some(1)) 的审查员。
【讨论】: