我正在使用Scala(2.1)进行编程,需要将一个Option[Long]
类型的值转换成Long
类型。
我知道如何实现相反的操作,也就是说:
def toOption[Long](value: Long): Option[Long] = if (value == null) None else Some(value)
但是在我的情况下,我必须将一个Option[Long]
类型的值传递给一个接受Long
类型的方法。
我正在使用Scala(2.1)进行编程,需要将一个Option[Long]
类型的值转换成Long
类型。
我知道如何实现相反的操作,也就是说:
def toOption[Long](value: Long): Option[Long] = if (value == null) None else Some(value)
但是在我的情况下,我必须将一个Option[Long]
类型的值传递给一个接受Long
类型的方法。
x.get
将会给你一个 Long 类型的结果。首先,你的“相反”实现存在一些严重问题。通过在方法上放置名为Long
的类型参数,你会遮蔽来自标准库的Long
类型。你可能的意思是以下内容:
首先,你的“相反”实现存在一些严重问题。通过在方法上放置名为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)
如果value
为空,则此方法将返回None
。
回答您的问题,假设我们有以下方法:
def foo(x: Long) = x * 2
通常不应该考虑将Option[Long]
传递给foo
,而是通过map
将foo
提升到Option
中:
scala> val x: Option[Long] = Some(100L)
x: Option[Long] = Some(100)
scala> x map foo
res14: Option[Long] = Some(200)
Option
的主要目的是在类型层次上模拟“空”值的可能性,以避免一整类 NullPointerException
问题。使用 Option
上的 map
允许您对可能存在于 Option
中的值执行计算,同时继续模拟它为空的可能性。
正如另一个答案所指出的那样,也可以使用 getOrElse
来“退出” Option
,但这通常不是 Scala 中的惯用做法(除非确实存在合理的默认值情况)。
该方法已定义在类型为 Option[A] 的对象上,称为 get :
scala> val x = Some(99L)
x: Some[Long] = Some(99)
scala> x.get
res0: Long = 99
问题在于对None调用get方法会抛出NoSuchElementException异常:
scala> None.get
java.util.NoSuchElementException: None.get
因此,使用Option类型将不会获得任何好处。
因此,如前所述,如果您可以提供合理的默认值或处理异常,可以使用getOrElse。
Scala的惯用方式是使用map或for循环。
x map (_ + 1)
res2: Option[Long] = Some(100)
或者for (i <- x) yield i +1
res3: Option[Long] = Some(100)
Option是本地化副作用的方法(您的函数可以返回空值)。将计算提升到Option是一种很好的风格(Option是具有map和flatMap方法的Monad)。
val x = Option[Long](10)
x.map { a => a + 10 }
通过手动处理副作用来提取值:
val res = x match {
case Some(a) => s"Value: $a"
case None => "no value"
}
当选项为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
除外)。如已经提到的那样,getOrElse 可能是您直接回答问题所寻找的答案。
请注意,要转换为选项,您可以简单地执行以下操作:
val myOption = Option(1)
myOption现在将变为Some(1)
val myOption = Option(null)
现在,myOption将变为None。
None
(这是Option[Long]
的一个可能值),调用get
会抛出错误。 - Andres F.