What is Some and Option?
Option
is a data structure that represents optionality, as the name suggests. Whenever a computation may not return a value, you can return an Option
. Option
has two cases (represented as two subclasses): Some
or None
.
In the example above, the method Email.fromString
can fail and not return a value. This is represented with Option
. In order to know whether the computation yielded a value or not, you can use match
and check whether it was a Some
or a None
:
Email.fromString("scala.center@epfl.ch") match {
case Some(email) => // do something if it's a Some
case None => // do something it it's a None
}
This is much better than returning null
because now whoever calls the method can't possibly forget to check the return value.
For example compare this:
def willReturnNull(s: String): String = null
willReturnNull("foo").length() // NullPointerException!
with this
def willReturnNone(s: String): Option[String] = None
willReturnNone("foo").length() // doesn't compile, because 'length' is not a member of `Option`
Also, note that using match
is just a way of working with Option
. Further discussion would involve using map
, flatMap
, getOrElse
or similar methods defined on Option
, but I feel it would be off-topic here.
What is a factory method (just some function that creates a new object and returns it?)
This is nothing specific to Scala. A "factory method" is usually a static method that constructs the value of some type, possibly hiding the details of the type itself. In this case fromString
is a factory method because it allows you create an Email
without calling the Email
constructor with new Email(...)
What is the point of companion objects? Is it just to contain functions that are available to all instances of class? Are they like class methods in Ruby?
As a first approximation, yes. Scala doesn't have static members of a class. Instead, you can have an object
associated with that class where you define everything that is static.
E.g. in Java you would have:
public class Email {
public String username;
public String domain;
public static Optional<Email> fromString(String: s) {
// ...
}
}
Where as in Scala you would define the same class as roughly:
class Email(val username: String, val domain: String)
object Email {
def fromString(s: String): Option[Email] = {
// ...
}
}