Option type, Some and None

The Option type is a very convenient way to avoid checking null pointers.
Here is a classical "null pointer checking" situation:
def getString : String = {
  ...
  "a string"
  ...
  null
}
 
val str = getString
val str2 = if (str == null) "[null]" else str
This code can be replaced by the following one:
def getString : Option[String] = {
  ...
  Some("a string")
  ...
  None
}
 
val str = getString.getOrElse("[null]")
It's using the Option type together with the Some case class and the None object (from Option.scala):
sealed abstract class Option[+A] extends Product {
  ...
}

final case class Some[+A](x: A) extends Option[A] {
  ...
}
 
case object None extends Option[Nothing] {
   ...
}
The rules are very simple:
  • replace your type T by Option[T]
  • instead of returning myInstance (an intance of type T), return Some(myInstance) which is of type Option[T]
  • instead of returning null, return None whose type is Option[Nothing] (the type Nothing being a subtype of every other type)
Then you just have to invoke the getOrElse method on your Option[T] instances:
/** If the option is nonempty return its value,
 *  otherwise return the result of evaluating a default expression.
 *
 *  @param default  the default expression.
 */
def getOrElse[B >: A](default: => B): B = ...
Here is another example based on a list of Option[String]:
// allows using String when Option[String] is required
implicit def str2optStr(s:String):Option[String] = Some(s)
 
// list of strings
// attention: do not use 'null', use 'None' instead
val strings = List[Option[String]](Some("some string"), None, "raw string") 
 
// using the getOrElse method
for (s <- strings) println( s.getOrElse("[null]") )
 
// using pattern matching
for (s <- strings) {
  s match {
    case Some(s:String) => println(s)
    case None => println("[null]")
     
    // The default case is useless because strings is of type List[Option[String]]
    // and the match is exhaustive with Some[String] and None
    //case _ =>
  }
}
Obviously some Scala classes use the Option type. Let's have a look to the source code of the scala.collection.Map class:
/** Check if this map maps key to a value and return the
 *  value if it exists.
 *
 *  @param  key the key of the mapping of interest
 *  @return     the value of the mapping, if it exists
 */
def get(key: A): Option[B]
   
/** Check if this map maps key to a value.
 *  Return that value if it exists, otherwise return default.
 */
def getOrElse[B2 >: B](key: A, default: => B2): B2 =
  get(key) match {
    case Some(v) => v
    case None => default
  }
You can see that the return type of the get method is Option[B] (where B is the type of the value associated with the key).
The getOrElse method calls the get method directly and matches the proper Option[B] pattern as shown in the previous example. The passed-in default function is invoked when the value associated with the key matches None (i.e. the key is not referenced within the map).

Here is a last example using the Map collection:
val stocks = Map (
  "Google" -> "GOOG",
  "Yahoo!" -> "YHOO",
  "IBM" -> "IBM",
  "Oracle" -> "ORCL"
)

val notFound = "[unknown]";
 
println(stocks.getOrElse("Yahoo!", notFound))
println(stocks.getOrElse("Apple", notFound))
This code produces the following output:
 YHOO
 [unknown]

For more information, please have a look to this article from David Pollack about a concrete use of the Option type within the Lift framework.