Option: No More null
Prerequisites: Collection operations, Match expressions
A value that might be missing has the type Option[A]: either
Some(value) or None. Idiomatic Scala uses Option instead of null,
so "might be missing" is visible in the type — and the compiler makes you
handle it.
@main def options(): Unit =
val emails = Map("ada" -> "ada@example.com")
val found: Option[String] = emails.get("ada")
val missing: Option[String] = emails.get("linus")
println(found)
println(missing)
println("42".toIntOption)
println("abc".toIntOption)
println(List(1, 2, 3).find(_ > 5))
Some(ada@example.com)
None
Some(42)
None
None
Many standard methods return Option: Map.get, toIntOption, find,
headOption, maxOption.
Getting the value out
@main def unwrap(): Unit =
val maybeAge: Option[Int] = "36".toIntOption
val noAge: Option[Int] = None
println(maybeAge.getOrElse(0))
println(noAge.getOrElse(0))
val message = noAge match
case Some(age) => s"Age is $age"
case None => "Age unknown"
println(message)
println(maybeAge.fold("unknown")(a => s"$a years"))
36
0
Age unknown
36 years
Transforming without unwrapping
Option works like a collection of zero or one elements, so map,
filter, and flatMap work on it:
@main def chains(): Unit =
def parse(s: String): Option[Int] = s.trim.toIntOption
println(parse(" 21 ").map(_ * 2))
println(parse("x").map(_ * 2))
println(parse("15").filter(_ >= 18))
println(parse("5").flatMap(n => if n > 0 then Some(100 / n) else None))
val total = for
a <- parse("10")
b <- parse("32")
yield a + b
println(total)
Some(42)
None
None
Some(20)
Some(42)
A chain continues as long as values are present, and short-circuits to
None as soon as one is missing — no if (x != null) checks.
Avoid .get
option.get returns the value but throws on None — it throws away
the safety Option gives you. Use getOrElse, match, map, or fold.
Practice
Write safeDivide(a: Int, b: Int): Option[Int] that returns None when
b is 0, and print the results for 10 / 2 and 10 / 0 with
getOrElse(-1).
Show solution
def safeDivide(a: Int, b: Int): Option[Int] =
if b == 0 then None else Some(a / b)
@main def divide(): Unit =
println(safeDivide(10, 2).getOrElse(-1))
println(safeDivide(10, 0).getOrElse(-1))
5
-1