戦略 Scala 日記

素人プログラマの思考のセンス

Optionにはifを使うなfilterを使え

ウェブアプリケーションを作っていると、下記のコードのvalue変数のように、値を受取るOption型の変数の中に値が入っている場合、かつ空文字列ではない場合のみ処理をしたいというケースはよくある。

val value: Option[String] = Some("1234")
if (value.isDefined && value.get.nonEmpty) {
  println("value: " + value.get)
}

上のコードを実行すると、valueの値がNoneの場合と、Some("")の場合は、ifブロック内の処理は行われない。 ただし、このような場合Scalaの得意とするパターンマッチを使ったほうがよい。 これをmatch caseを使って書き換えてみる。

val value: Option[String] = Some("1234")
value match {
  case Some(x) if x.nonEmpty => println("value: " + x)
  case _ => 
}

しかし、今回のように、valueが条件に一致しない場合はなにも処理をしないような場合は、case matchを使っても冗長になる。 こういったケースでは、ifを使って分岐をするより、filterに処理する条件を渡したほうがコードの見通しが良くなる。

val value: Option[String] = Some("1234")
value.filter(_.nonEmpty).foreach(println)

filtermapforeachのようにコレクションAPIを利用すると、Option型がNoneの場合は処理されない。

val value: Option[String] = None
value.foreach(println)