“Convert” Option[x] to x in Scala

两盒软妹~` 提交于 2019-12-03 08:30:01

问题


I working with play for scala (2.1) and I need to convert an "Option[Long]" value to "Long".

I know how to do the opposite, I mean:

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

But in my case, I have to pass a value of "Option[Long]" as a type into a method that takes "Long". Any help please.


回答1:


First of all, your implementation of "the opposite" has some serious problems. By putting a type parameter named Long on the method you're shadowing the Long type from the standard library. You probably mean the following instead:

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

Even this is kind of nonsensical (since scala.Long is not a reference type and can never be null), unless you're referring to java.lang.Long, which is a recipe for pain and confusion. Finally, even if you were dealing with a reference type (like String), you'd be better off writing the following, which is exactly equivalent:

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

This method will return None if and only if value is null.

To address your question, suppose we have the following method:

def foo(x: Long) = x * 2

You shouldn't generally think in terms of passing an Option[Long] to foo, but rather of "lifting" foo into the Option via map:

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

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

The whole point of Option is to model (at the type level) the possibility of a "null" value in order to avoid a whole class of NullPointerException-y problems. Using map on the Option allows you to perform computations on the value that may be in the Option while continuing to model the possibility that it's empty.

As another answer notes, it's also possible to use getOrElse to "bail out" of the Option, but this usually isn't the idiomatic approach in Scala (except in cases where there really is a reasonable default value).




回答2:


If you have x as Option[Long], x.get will give you Long.




回答3:


This method is already defined on Option[A] and is called get :

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

scala> x.get
res0: Long = 99

The problem is that calling get on None will throw a NoSucheElement Exception:

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

thus you will not gain any benefits from using an Option type.

Thus as stated before you can use getOrElse if you can provide a sensible default value or handle the Exception.

The idiomatic scala way would be using map or a for-comprehension

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

or

for (i <- x) yield i +1
res3: Option[Long] = Some(100)



回答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"
} 



回答5:


You need to decide what happens when the option is None. Do you provide a default value?

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

unroll(None) // -> -1

You could also throw an exception:

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

unroll(None) // -> exception

In case, refrain from using null, unless you have very good reasons to use it (opt.orNull).




回答6:


As has already been mentioned getOrElse is probably what you're looking for in answering your question directly.

Please note also that to convert to an option you can simply:

val myOption = Option(1)

myOption will now be Some(1)

val myOption = Option(null)

myOption will now be None.



来源:https://stackoverflow.com/questions/19765713/convert-optionx-to-x-in-scala

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!