CHAPTER 2 ■ SCALA SYNTAX, SCRIPTS, AND YOUR FIRST SCALA PROGRAMS
17
return type can be inferred and the method is not recursive.
2
We declare the return type
as
Option[Int]. In general, if the return type is not immediately obvious, it’s an act of kind-
ness and good citizenship to your fellow programmers and your future self to declare the
return type.
What’s
Option and what are those funky square brackets around Int? Option is a container
that holds one or zero things. If it holds zero elements, it’s
None, which is a singleton, which
means that only one instance of
None. If the Option holds one element, it’s Some(theElement).
The funky square brackets denote the type of thing that’s held by the
Option. In this
case, the
Option holds an Int.
In Scala, everything is an instance of a class, even
Int, Char, Boolean, and the other JVM
primitive types. The Scala compiler puts primitive types in instance boxes (boxing) only
when necessary. The result is that you can treat all classes uniformly in Scala, but if your
primitive data does not require boxing, you’ll see the same program performance you see
using primitives in Java. If your primitive does require boxing, the Scala compiler does all
the boxing and unboxing for you, and it even does
null testing when it unboxes—nice and
polite.
So,
Option[Int] is a container that holds zero or one Int value.
3
Using Option is one of
the ways that Scala lets you avoid
null pointer exceptions and explicit null testing. How?
You can apply your business logic over all the elements in the
Option. If the Option is None,
then you apply your logic over zero elements. If the
Option is Some, then you apply your
business logic over one element.
Option can be used and nested in the for comprehen-
sion. We’ll explore
Option in more depth in Chapter 3.
When I’m writing code, I return
Option from any method that, based on business logic,
might return some value or might return none. In this case, converting a
String to an Int
might succeed if the
String can be parsed or might fail if the String cannot be parsed into
an
Int. If the String cannot be parsed, it is not something that’s worthy of an exception
because it’s not an exceptional situation. It is merely a calculation that has no legal value,
thus it makes sense to return
None if the String cannot be parsed. This mechanism also
avoids the Java patchwork of sometimes returning
null when there’s no legal value to
return and sometimes throwing an exception.
Speaking of exceptions, that’s exactly what
Integer.parseInt does when it cannot
parse the
String into an Int. So, in our code, we wrap a try/catch around
Some(Integer.parseInt(in.trim)). If the Integer.parseInt method succeeds, a new
instance of
Some will be created and returned from the toInt method. There’s no explicit
return statement as the last expression evaluated in the method is its return value.
2. A recursive method is a method that calls itself.
3. Option[Int] is a “variant type” or “sum type” with
None as one variant and Some[Int] as the other.
Neither None nor Some[Int] is the same as Int, but if you’re working with an Option[Int] that happens
to be of the variant Some[Int] then you can extract the actual
Int from it by calling the get method.
19897ch02.fm Page 17 Wednesday, April 1, 2009 5:34 PM