2012年1月20日金曜日

Scala Tips/Option

プログラミング言語の習得で重要なことの一つは、局面ごとに使うイディオムを体で覚えて無意識に出てくるようにすることです。

Scalaでのイディオムも少し見えてきたので、少しずつ整理していきたいと思います。

基本文法を覚えたての知識でのコーディングからScalazまでを併置するようにしました。以下のような分類にしています。

Java風
Javaプログラミングの感覚でコーディングしたもの
Scala風
Scalaらしい文法を使っているが、少し泥臭い感じ
Scala
Scalaでのイディオム
Scalaz
Scalazでのイディオム

Java風、Scala風は問題を明確にするための参考情報で、ScalaまたはScalazが推奨の方法です。

今回は、Optionから値を取り出す時に、Noneの場合デフォルト値を使用する方法です。

Java風

if式でOptionのisDefinedメソッドを判定します。安全確実ですが、if式、Option#isDefined、Option#getが出てきたら、Scala的にはちょっと負けっぽい。

Option#isDefinedとOption#getが何かの拍子で泣き別れになるとバグの元になるので、この組合せはできるだけ避けたいわけです。

def f(a: Option[Int]): Int = {
  if (a.isDefined) a.get
  else 0
}

Scala風

match式を使うことで、if式、Option#isDefined、Option#getが見えなくなりました。ただ、やろうとしていることに対して記述がやや冗長な感触です。

def f(a: Option[Int]): Int = {
  a match {
    case Some(b) => b
    case None => 0
  }
}

Scala

Optionに目的にぴったりあうメソッドgetOrElseがあるので、これを使うのがイディオム。事前に用意されているメソッドを使うだけなのでイディオムと呼ぶのはやや大げさですが、ユースケースに対する解を、考えて分かるのではなく、無意識に出てくるのが大事なので、イディオムとして取り上げています。

def f(a: Option[Int]): Int = {
  a getOrElse 0
}

Scalaz

Scalazの場合は"|"でデフォルト値をより簡潔に記述することができます。

def f(a: Option[Int]): Int = {
  a | 0
}

0 件のコメント:

コメントを投稿