...
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 件のコメント:
コメントを投稿