Published 2014-01-11.
Last modified 2019-04-22.
Time to read: 3 minutes.
Scala’s Option
provides a way to eliminate null pointer exceptions.

The source code for this lecture is in
courseNotes/
.
Java methods often return null
when there is no value to be returned.
This is a leading source of runtime errors.
Scala offers the Option
container, which allows you to handle the two cases:
Some
value is returned, or the value is None
.
The Option
construct has been cleverly implemented, and it is actually a collection of zero or one items.
That means you can iterate over its contents to work with any value that might be within.
Because Option
is a container, when you declare a variable to be of type Option
you must also declare the type that may be contained by the Option
.
For example, here is how we could declare a variable called maybeAnswer
, which might contain an Int
.
The value stored in the variable is wrapped in a subclass of Option
called Some
,
which contains the value we are interested in.
scala> val maybeAnswer: Option[Int] = Some(42) maybeAnswer: Option[Int] = Some(42)
Scala 2.13 introduced the
StringOps.toIntOption
method, which attempts to parse an Int from a String
.
The toIntOption
method either returns Some[Int]
or None
if the parse was unsuccessful.
scala> val maybeAnswer: Option[Int] = "42".toIntOption res0: Option[Int] = Some(42)
We can obtain the value of an Option
that has Some
value with get
,
although that is not what you should usually do.
More on that later.
scala> maybeAnswer.get res1: Int = 42
We’ll look at the other StringOps.toXXXOption
methods in a moment.
Similarly, we can declare a variable that might contain a String
containing the name of our favorite type of chocolate, or
None
if we don’t like chocolate.
scala> val maybeFavorite: Option[String] = None maybeFavorite: Option[String] = None
scala> maybeFavorite.getOrElse("Bleah!") res1: String = Bleah!
However, if we attempt to obtain the value of our favorite chocolate, we will get an error if we use get.
Instead, we use getOrElse
, which provides a default value if the Option
contains None
:
scala> maybeFavorite.get java.util.NoSuchElementException: None.get
scala> maybeFavorite.getOrElse("Nope") res6: String = Nope
We can also perform an action if an Option
contains Some
value:
scala> maybeAnswer.foreach { x => println(3 * x) } // prints the value of 42 times 3 126
scala> maybeFavorite.foreach { println } // does not print anything
If an Option
has Some
value, its isDefined
method will return true;
otherwise, if the Option
has None
value isEmpty
will return true
.
scala> val object1 = Some("Hi there") object1: Some[java.lang.String] = Some(Hi there)
scala> object1.isDefined res11: Boolean = true
scala> object1.isEmpty res12: Boolean = false
scala> val object2 = None object2: None.type = None
scala> object2.isDefined res13: Boolean = false
scala> object2.isEmpty res14: Boolean = true
Scala 2.13’s Other StringOps.toXXXOption Methods
Scala 2.13 introduced better StringOps
parsing methods in addition to toIntOption
,
which we have already seen.
scala> "true".toBooleanOption res3: Option[Boolean] = Some(true)
scala> "false".toBooleanOption res4: Option[Boolean] = Some(false)
scala> "true".toBooleanOption.foreach( if (_) println("Yes"); else println("No") ) Yes
scala> "asdf".toBooleanOption.foreach( if (_) println("Yes"); else println("No") ) No output because foreach does not iterate over None
scala> "asdf".toBooleanOption.map( if (_) "Yes"; else "No" ) res5: Option[String] = None
scala> "123".toBooleanOption res6: Option[Boolean] = None
scala> "1".toDoubleOption res7: Option[Double] = Some(1.0)
scala> "asdf".toDoubleOption res8: Option[Double] = None
Wrapping Nulls with Option

Here is where Option
gets interesting.
First imagine that you want to retrieve the value of an environment variable.
scala> Option(System.getProperty("os.name")) res15: Option[java.lang.String] = Some(Windows 7)
Because we are sure that the result is wrapped in a Some
instance, we call get
to retrieve it
(we will discover soon that it usually is better to use map
,
foreach
or other iterators instead of calling get
).
scala> Option(System.getProperty("os.name")).get res16: java.lang.String = Windows 7
If the environment variable is not set, Option
will return None
instead of null
.
scala> Option(System.getProperty("not.present")) res17: Option[java.lang.String] = None
orElse
We can use orElse()
to provide a default value if the Option
’s value was None
.
scala> Option(System.getProperty("not.present")).orElse(Some("default")) res3: Option[String] = Some(default)
scala> Option(System.getProperty("os.name")).orElse(Some("default")) res4: Option[String] = Some(Linux)
The above returns an Option
if the system property has a value or not.
Now we can use get
to retrieve whichever value comes back.
scala> Option(System.getProperty("not.present")).orElse(Some("default")).get res19: Option[java.lang.String] = default
getOrElse
We can use getOrElse
to retrieve the value of the Option
,
or the value of the getOrElse
arguments if the
Option
’s value was None
.
scala> Option(System.getProperty("not.present")).getOrElse("default") res18: String = default
scala> Option(System.getProperty("os.name")).getOrElse("default") res6: String = Linux
Option
is actually a collection of zero or one items.
This means that collection operations work on Option
instances.
This leads to useful Scala idioms, such as provided by Option.fold
.
We will discuss that in the next course.
It is also helpful to think of Option
as a container.
Exercise
Write a Scala console app that checks the value of an environment variable.
If it is defined, print out its value, otherwise print out "undefined
".
Solution
This solution can be found in
courseNotes/
".
object TupleAnswer extends App {
def osProp(name: String): String = Option(System.getProperty(name)).getOrElse("undefined")
if (args.length>=1)
println(s"""Value of ’${args(0)}’ system property is ’${osProp(args(0))}’""")
}
To run it, type:
$ sbt "runMain solutions.TupleAnswer os.name"
$ sbt "runMain solutions.TupleAnswer user.home"
© Copyright 1994-2024 Michael Slinn. All rights reserved.
If you would like to request to use this copyright-protected work in any manner,
please send an email.
This website was made using Jekyll and Mike Slinn’s Jekyll Plugins.