minimize

事業拡大のため、新しい仲間を募集しています。
→詳しくはこちら

Option と Some

Scala には、Option[T] という型がある。
T は任意の型だが、よく使われるのは Int などの数値型のようだ。
以下のように使う。

val id : Option[Long]

id =
  if (bean.id.text != "")
    Some(bean.id.text.toLong)
  else
    None

Option[Long] は、Some(Long) または None のいずれかの値を取る。
見て大体わかると思うが、前者は値が存在すること、後者は値が存在しないことを表す。

通常の Java では、これらは Long クラスを使って null によって値が存在しないことを表していた。
※ Scala の Long は scala.Long であり、Java の java.lang.Long とは異なる
Scala では、None という明確な「存在しないこと」を表すオブジェクトがある。

使う側は以下のようにする。

if (id.isEmpty) {
  number = id.get;
} else {
  ...
}

このようにすると、Some の中身を取り出せる。
もっと Scala っぽくやるならば、パターンマッチング を使おう。

val nameMaybe = request.getParameter("name")
nameMaybe match {
  case Some(name) => {
    println(name.trim.toUppercase)
  }
  case None => {
    println("No name value")
  }
}

雑記

ここまで読んで「null 判定で別にいいじゃん」という声もあるだろうが、一番大事なのは
「値が無いという可能性があること」を使う側に明示的に示しているということ。

例えば、null の可能性がある String を受け取ったときに使う側は何の躊躇いもなく

str.toUppercase

とやるかもしれない。値が null ならそこで NullPointerException が発生してしまう。

Option[T] を使うことによって、作る側も使う側も「この値は None である可能性がある」ということを
はっきりと認識できる。もし認識しないで使おうとしたらコンパイルエラーになるだろう。
Some(T) はそのままでは使えないからだ。

Option[T] は、プログラマが長年苦しんできたNullable(ヌル可能性)の問題を解決するために
Scala が取った答えなのだ。Scala を使うなら、その流儀に従って Option[T] を使おう。