Scala has a type to hold optional values named Option. It can be of two types:
Some(x)
, where x is an actual value or
None
, which represents a missing value.
An Option is actually an abstract class with two implementations where Some is a case class, and None is an object.
Optional values are generated as a result of some operations on the Scala collections.
For example:
val mapExample = Map("One" -> 1, "Two" -> 2)
val result: Option[Int] = mapExample.get("One")
val result: Option[Int] = mapExample.get("Three")
val mapExample: scala.collection.immutable.Map[String,Int] = Map(One -> 1, Two -> 2)
val result: Option[Int] = Some(1)
val result: Option[Int] = None
How to Extract Value From an Option?
1) Using get method
Example:
Val res0 = Some("Name").get
None.get
Output:
val res0: String = Name
java.util.NoSuchElementException: None.get
at scala.None$.get(Option.scala:627)
... 36 elided
The get method on the None type can result in an error. So, we should first check if Option has a value before using get on Option. To check if the Option field has some value defined, you can use the method “ isDefined ”.
2) Using getOrElse
getOrElse method provides one flexibility on top of the get method to return a default value if the Option does not contain any value(i.e., it is of None type) but getOrElse is not type-safe.
val res4 = Some("Name").getOrElse("")
val res5 = None.getOrElse("default value")
Output:
val res4: String = Name
val res5: String = default value
We can look at the below example to see how this method is not type-safe.
Some("Name").getOrElse(5) //Output will result into Any type
When getOrElse is applied on an Option[String], ideally, it should result in string type after extracting value from it. But getOrElse let us provide a different type value in the default argument.
3) Using fold
Below is the declaration of the fold method:
final def fold[B](ifEmpty : => B)(f : scala.Function1[A, B])
The fold method takes two arguments, the first will be executed if the option type is None, and the second will be executed if the option type is Some.
Below are examples of how you can use fold.
println(Some("Name").fold("default")(identity))
println(Some("Name").fold("defaultValue")(_.toString))
println(Some("Name").fold("")(_.toUpperCase()))
println(None.fold("defaultValue")(_.toString))
Output:
Name
Name
NAME
defaultValue
One additional benefit of using fold is that fold is typesafe, so if you try to provide different type values in both arguments, it will lead to an error.
Example:
Some("Name").fold(5)(_.toUpperCase)
// above statement will lead to compilation part. The first argument suggests that the return type is Int, while the second argument suggests that the return type is String.
4) Using pattern match
Example:
val response = Option("TGB Learner")
val x = response match {
case Some(data) => "TGB Learner"
case None => "Technology excites me"
}
println(x)
Output:
val response: Option[String] = Some(TGB Learner)
val x: String = TGB Learner