あるプログラマの日記

プログラマのメモ、出来事、考えたこと、勉強とかの雑記

パターンマッチ (基本のメモ)

  • パターンマッチは条件分岐を記述する switch 文に似た構文
  • 主にデータの比較、分解、抽出の用途で使用する。
  • 実行時に該当するパターンが選択肢にない場合は scala.MatchError が発生する。
  • switch の default はないが、default と同等のパターンとしてワイルカードを指定できる。
  • Scala のパターンマッチには break は不要で上から順番にマッチするまで評価してマッチした後は自動で制御から抜ける。
セレクタ式 match {
  case パターン1 => 処理1
  case パターン2 => 処理2
  case ...
  case _ => 上記バターン以外の処理
}
  • パターンに該当した後は => の後の処理が順番に評価される。
  • パターンに記述できるものが C や java の switch 文よりもはるかに柔軟で豊富
パターンの種類 記述例 内容
ワイルドカード case _ あらゆるオブジェクトにマッチ
リテラル(整数) case 1 整数 1 であればマッチ
リテラル(文字列) case "foo" 文字列 "foo" であれば
定数(空のリスト) *1 case Nil 空リストだけにマッチ
変数 *2 case v すべてにマッチ。結果を変数 v に束縛する
case v: Long Long型であれば
コンストラク case Foo(1, n) *3 case クラスのオブジェクトがマッチ。さらにコンストラクタ引数のマッチ
タプル case (a, b) a と b の変数を持つTuple2であれば
シーケンス case x :: xs 先頭要素と残りリスト要素があれば
パターンガード case (a, b) if (a % 2) == 0 細かい条件分岐を行う場合はガード条件(ifの条件)を付ける

case クラスの定義

  • class 宣言の前に case を付ける。
  • case クラスはフィールド宣言の必要がない。コンストラクタの引数が自動的にフィールドとして扱われる。
  • toString, hashCode, equals, copy メソッドはコンパイラが自動で実装を追加してくれる。
  • Scala はクラス本体が空であれば中括弧({ })を省略可能
scala> case class Foo(a: Int, b: Long)
defined class Foo

scala> val v = Foo(1, 2L)
v: Foo = Foo(1,2)

scala> val v2 = v.copy(a = 3)
v2: Foo = Foo(3,2)

scala> v == v2
res0: Boolean = false

*1:先頭が小文字でないものは定数とみなされる

*2:パターン変数は小文字で始める必要がある

*3:引数リスト内の引数には暗黙に val が付けられるためフィールドとして扱える