... val a = new MatchSampleClass; a match { case MatchSampleClass(x, y) => println("x: " + x + " y: " + y); case _ => println("OTHER: " + a); } .... class MatchSampleClass object MatchSampleClass { def unapply(obj : MatchSampleClass) : Option[(String, String)] = { return Option(("ONE", "TWO")); } }
x: ONE y: TWO
unpapply は Tupple を Some オブジェクトでラップして返す。
case 句では「MatchSampleClass(x, y)」と MatchSampleClass.apply が呼ばれそうな構文になっているが、 実際には unapply が呼ばれるだけで、apply メソッドが定義されている必要はない。
unapply の代わりに unapplySeq を定義してもよい。
unapplySeq では Tuple の代わりに Seq オブジェクトを Some オブジェクトでラップして返す。
... val a = new MatchSampleClass; a match { case MatchSampleClass(x, y) => println("x: " + x + " y: " + y); case _ => println("OTHER: " + a); } .... class MatchSampleClass object MatchSampleClass { def unapplySeq(obj : MatchSampleClass) : Option[List[String]] = { return Option(List("ONE","TWO")); } }
x: ONE y: TWO
unapply と unapplySeq の使われ方
クラスが unapply と unapplySeq が定義されている場合は unapply が使われる。
unapply では抽出されるオブジェクト数が固定なので以下のようなコードはコンパイル時にエラーになる。
... val a = new MatchSampleClass; a match { case MatchSampleClass(x, "AAA", z) => println(" x: " + x); case _ => println("OTHER: " + a); } ... class MatchSampleClass object MatchSampleClass { def unapplySeq(obj : MatchSampleClass) : Option[List[String]] = { return Option(List("ONE", "TWO")); } def unapply(obj : MatchSampleClass) : Option[(String, String)] = { return Option(("ONE", "TWO")); } }
wrong number of arguments for object MatchSampleClass
このコードで unapply の定義を削除すると可変長の unapplySeq が使われるのでエラーにはならない。上のコードの場合はビルドエラーにはならないがマッチもしないので、case _ の節が実行される。
実際に unapply や unapplySeq が実行されるのは1回だけ。各case節ごとに実行されるわけではない。
... val a = new MatchSampleClass; a match { case MatchSampleClass(x, "AAA") => println(" x: " + x); case MatchSampleClass(x,y) => println("x: " + x + " y: " + y); case _ => println("OTHER: " + a); } ... class MatchSampleClass object MatchSampleClass { def unapply(obj : MatchSampleClass) : Option[(String, String)] = { println("unapply Called") return Option(("ONE", "TWO")); } }
unapply Called x: ONE y: TWO
最初のcase 句にはマッチしないため2番目の case 句でマッチしているが、 unapply 自体は1回しか実行されていない。 最初に引数リストに分解し、それが各 case 句にマッチするかを調べるような作りになっているようだ。
0 件のコメント:
コメントを投稿