Scalaの旅8抽出器オブジェクト(ExtractorObject)
1916 ワード
Scalaでは,パターンはCase Classとは独立に定義され,unapplyという名前の方法が抽出器を生成するために用いられる.たとえば、次のコードは抽出オブジェクトTwiceを定義します.
コードを正常に動作させるには、2つの構文規則があります.
1.パターンcase Twice(n)はTwiceを呼び出す.unapplyは偶数に一致します.unapplyの戻り値は、パラメータが一致するかどうかを識別します.例では、z/2はマッチングに引き続き使用されます.
2.applyはモードマッチングに必要なものではなく、コンストラクタをシミュレートするために使用されます.val x=Twice(21)はval x=Twiceに等価である.apply(21).
unapplyの戻りクラスはOption[Int]であり,実際には3つの可能性がある.
1.テストのみの場合は、ase even()と同様にBooleanを返します.
2.戻りタイプTセットとの要素のうちの1つを返し、戻りタイプはOption[T]である
3.一連のタイプTの要素T 1を返したい場合、…、Tn,それらを1つのメタグループOption[(T 1,...,Tn)]に組み合わせる.
返される要素の個数が固定されている場合もあれば、シーケンスを返す必要がある場合もあります.最上位のunapplySeqモードがあり、最後の要素TnのタイプはSeq[S]でなければならないので、case List(x 1,...,xn)モードを使用することができます.
実は上の例ですが、パラメータ値が21なのか他の数なのか、出力はいつも自身です.どうして?シミュレータコンストラクタは常に偶数を返すので、出力もそれ自体です.次のように変更できます.
または
これはもっと面白いです.Someの定義は次のとおりです.
object Twice {
def apply(x: Int): Int = x * 2
def unapply(z: Int): Option[Int] = if (z%2 == 0) Some(z/2) else None
}
object TwiceTest extends Application {
val x = Twice(21)
x match { case Twice(n) => Console.println(n) } // prints 21
}
コードを正常に動作させるには、2つの構文規則があります.
1.パターンcase Twice(n)はTwiceを呼び出す.unapplyは偶数に一致します.unapplyの戻り値は、パラメータが一致するかどうかを識別します.例では、z/2はマッチングに引き続き使用されます.
2.applyはモードマッチングに必要なものではなく、コンストラクタをシミュレートするために使用されます.val x=Twice(21)はval x=Twiceに等価である.apply(21).
unapplyの戻りクラスはOption[Int]であり,実際には3つの可能性がある.
1.テストのみの場合は、ase even()と同様にBooleanを返します.
2.戻りタイプTセットとの要素のうちの1つを返し、戻りタイプはOption[T]である
3.一連のタイプTの要素T 1を返したい場合、…、Tn,それらを1つのメタグループOption[(T 1,...,Tn)]に組み合わせる.
返される要素の個数が固定されている場合もあれば、シーケンスを返す必要がある場合もあります.最上位のunapplySeqモードがあり、最後の要素TnのタイプはSeq[S]でなければならないので、case List(x 1,...,xn)モードを使用することができます.
実は上の例ですが、パラメータ値が21なのか他の数なのか、出力はいつも自身です.どうして?シミュレータコンストラクタは常に偶数を返すので、出力もそれ自体です.次のように変更できます.
object Twice {
def apply(x: Int): Int = x
def unapply(z: Int): Option[Int] = if (z%2 == 0) Some(z/2) else None
}
object TwiceTest extends Application {
val x = Twice(13)
x match { case Twice(n) => Console.println(n) case _ => Console.println("None")}
}
または
object Twice {
def apply(x: Int): Int = x * 2
def unapply(z: Int): Option[Int] = if (z%3 == 0) Some(z/2) else None
}
object TwiceTest extends Application {
val x = Twice(13)
x match { case Twice(n) => Console.println(n) case _ => Console.println("None")}
}
これはもっと面白いです.Someの定義は次のとおりです.
final case class Some[+A](x: A) extends Option[A] {
def isEmpty = false
def get = x
}