Scala-エクストラクター

Scalaのエクストラクタは、次のメソッドを持つオブジェクトです。 unapplyそのメンバーの一人として。そのunapplyメソッドの目的は、値を一致させて分解することです。多くの場合、エクストラクタオブジェクトはデュアルメソッドも定義しますapply 価値を構築するためですが、これは必須ではありません。

オブジェクトが両方を定義する例を見てみましょう apply そして unapplyメソッド。applyメソッドの意味はいつもと同じです。つまり、メソッドが適用されるのと同じ方法で、Testを括弧内の引数に適用できるオブジェクトに変換します。したがって、Test( "Zara"、 "gmail.com")を記述して、文字列 "[email protected]"を作成できます。

ザ・ unapply メソッドは、テストクラスを extractor そしてそれはの建設プロセスを逆にします apply。applyが2つの文字列を受け取り、それらから電子メールアドレス文字列を形成する場合、unapplyは電子メールアドレスを取り、潜在的に2つの文字列を返します。user そしてその domain アドレスの。

ザ・ unapply指定された文字列が電子メールアドレスでない場合も処理する必要があります。そのため、unapplyは文字列のペアに対してOptionタイプを返します。その結果はどちらかですSome (user, domain)文字列strが指定されたユーザーとドメイン部分を持つ電子メールアドレスである場合、またはstrが電子メールアドレスでない場合はNone。以下にいくつかの例を示します。

構文

unapply("[email protected]") equals Some("Zara", "gmail.com")
unapply("Zara Ali") equals None

次のサンプルプログラムは、電子メールアドレスの抽出オブジェクトを示しています。

object Demo {
   def main(args: Array[String]) {
      println ("Apply method : " + apply("Zara", "gmail.com"));
      println ("Unapply method : " + unapply("[email protected]"));
      println ("Unapply method : " + unapply("Zara Ali"));
   }
   
   // The injection method (optional)
   def apply(user: String, domain: String) = {
      user +"@"+ domain
   }

   // The extraction method (mandatory)
   def unapply(str: String): Option[(String, String)] = {
      val parts = str split "@"
      
      if (parts.length == 2){
         Some(parts(0), parts(1)) 
      } else {
         None
      }
   }
}

上記のプログラムをに保存します Demo.scala。このプログラムをコンパイルして実行するには、次のコマンドを使用します。

コマンド

\>scalac Demo.scala
\>scala Demo

出力

Apply method : [email protected]
Unapply method : Some((Zara,gmail.com))
Unapply method : None

エクストラクタを使用したパターンマッチング

クラスのインスタンスの後に0個以上のパラメーターのリストを含む括弧が続く場合、コンパイラーは applyそのインスタンスのメソッド。オブジェクトとクラスの両方でapplyを定義できます。

上記のように、の目的は unapply方法は、探している特定の値を抽出することです。逆の操作をしますapplyします。を使用して抽出オブジェクトを比較する場合match 声明 unapply メソッドは自動的に実行されます。

次のサンプルプログラムを試してください。

object Demo {
   def main(args: Array[String]) {
      val x = Demo(5)
      println(x)

      x match {
         case Demo(num) => println(x+" is bigger two times than "+num)
         
         //unapply is invoked
         case _ => println("i cannot calculate")
      }
   }
   def apply(x: Int) = x*2
   def unapply(z: Int): Option[Int] = if (z%2==0) Some(z/2) else None
}

上記のプログラムをに保存します Demo.scala。このプログラムをコンパイルして実行するには、次のコマンドを使用します。

コマンド

\>scalac Demo.scala
\>scala Demo

出力

10
10 is bigger two times than 5