ケースクラスとパターンマッチング

ケースクラス(case class)は、Scala の強力なパターンマッチングのために必要なものらしい。普通のクラス(class)とどう違うのかよくわからないけど、パターンマッチングに使いたければケースクラスにしておけ、くらいに覚えておく(とりあえず)。

ケースクラスは次のように case キーワードをつけて宣言する。

scala> sealed abstract class DayOfWeek
defined class DayOfWeek

scala> case object Sunday extends DayOfWeek
defined object Sunday

scala> case object Monday extends DayOfWeek
defined object Monday

scala> case object Tuesday extends DayOfWeek
defined object Tuesday

scala> case object Wednesday extends DayOfWeek
defined object Wednesday

scala> case object Thursday extends DayOfWeek
defined object Thursday

scala> case object Friday extends DayOfWeek
defined object Friday

scala> case object Saturday extends DayOfWeek
defined object Saturday

クラスだと言っておきながらオブジェクト(object)なんだけど、どっちでもいいってことなんだろうか。ともかくこれらは次のようにパターンマッチングに使える。

scala> val x: DayOfWeek = Tuesday
x: DayOfWeek = Tuesday

scala> x match {
     |     case Sunday => 0
     |     case Monday => 1
     |     case Tuesday => 2
     |     case Wednesday => 3
     |     case Thursday => 4
     |     case Friday => 5
     | }
<console>:19: warning: match may not be exhaustive.
It would fail on the following inputs: Saturday
       x match {
       ^
res1: Int = 2

曜日を表すオブジェクトに対応する整数を返すコードだけど、今日(x)は火曜日なので 2 が返ってきている。

警告が出ているのは、マッチの分岐が完全じゃないかもしれないってこと。実際 Saturday が抜けている。これは、スーパークラス/トレイトの宣言に sealed 修飾子をつけるとその(直接の)サブクラス/トレイト(オブジェクトも?)は同じファイル内にしか宣言できない、という性質を利用して実現されている。

sealed 修飾子はこの用途以外ではめったに使われないので、ケースクラスのスーパークラス/トレイトには sealed をつけておくものだと覚えておこう。

パターンマッチングはもっと強力なんだけど、今日のところはこのへんで。