32

我使用 scala (2.1) 的游戏,我需要将“Option[Long]”值转换为“Long”。

我知道如何做相反的事情,我的意思是:

  def toOption[Long](value: Long): Option[Long] = if (value == null) None else Some(value)

但就我而言,我必须将“Option[Long]”的值作为类型传递给采用“Long”的方法。请提供任何帮助。

4

6 回答 6

59

如果你有 x 作为 Option[Long],x.get会给你 Long。

于 2014-05-19T09:05:31.233 回答
32

首先,您对“相反”的实施存在一些严重的问题。通过在方法上放置一个类型参数Long,您可以Long从标准库中隐藏类型。您可能指的是以下内容:

def toOption(value: Long): Option[Long] =
  if (value == null) None else Some(value)

即使这是一种荒谬的做法(因为scala.Long它不是引用类型并且永远不可能是null),除非您指的是java.lang.Long,这是痛苦和混乱的秘诀。最后,即使您正在处理引用类型(如String),您最好编写以下内容,这是完全等价的:

def toOption(value: String): Option[String] = Option(value)

None当且仅当valueis时,此方法才会返回null

为了解决您的问题,假设我们有以下方法:

def foo(x: Long) = x * 2

您通常不应该考虑传递Option[Long]to foo,而是“提升”fooOptionvia map

scala> val x: Option[Long] = Some(100L)
x: Option[Long] = Some(100)

scala> x map foo
res14: Option[Long] = Some(200)

的重点Option是(在类型级别)建模“空”值的可能性,以避免整个类的NullPointerException-y 问题。使用maponOption允许您对可能存在的值执行计算,Option同时继续建模它为空的可能性。

正如另一个答案所指出的,也可以用来getOrElse“纾困” Option,但这通常不是 Scala 中的惯用方法(除非确实存在合理的默认值)。

于 2013-11-04T10:40:34.730 回答
11

此方法已在 Option[A] 上定义并称为get

scala> val x = Some(99L)
x: Some[Long] = Some(99)

scala> x.get
res0: Long = 99

问题是在 None 上调用 get 会抛出 NoSucheElement 异常:

scala> None.get
java.util.NoSuchElementException: None.get

因此,您不会从使用 Option 类型中获得任何好处。

因此,如前所述,如果您可以提供合理的默认值或处理异常,则可以使用getOrElse 。

惯用的 scala 方式将使用 map 或 for-comprehension

x map (_ + 1)
res2: Option[Long] = Some(100)

或者

for (i <- x) yield i +1
res3: Option[Long] = Some(100)
于 2013-11-04T13:33:17.530 回答
4

Option is way to localise side-effect (your function can return empty value). And good style to lift your computation to Option (Option is Monad with map & flatMap methods).

val x = Option[Long](10) 
x.map { a => a + 10 }

And extract value with manually processing of side effect:

val res = x match {
  case Some(a) => s"Value: $a"
  case None    => "no value"
} 
于 2013-11-04T12:50:34.267 回答
1

您需要确定选项是什么时候会发生的None。您是否提供默认值?

def unroll(opt: Option[Long]): Long = opt getOrElse -1L  // -1 if undefined

unroll(None) // -> -1

你也可以抛出异常:

def unroll(opt: Option[Long]): Long = opt.getOrElse(throw 
  new IllegalArgumentException("The option is expected to be defined at this point")
)

unroll(None) // -> exception

以防万一,请不要使用null,除非您有充分的理由使用它 ( opt.orNull)。

于 2013-11-04T10:37:14.187 回答
0

正如已经提到的,getOrElse 可能是您在直接回答问题时要寻找的东西。

另请注意,要转换为选项,您可以简单地:

val myOption = Option(1)

myOption 现在将是 Some(1)

val myOption = Option(null)

myOption 现在将为 None。

于 2013-11-04T19:33:51.100 回答