Scala エクストラクタ(Extractor)

エクストラクタは、渡されたオブジェクトからオブジェクトの構築に使用されるパラメータを抽出します。

Scala標準ライブラリにはいくつかの事前定義済のエクストラクタが含まれています。次にはそれを説明します。

Scalaエクストラクタは、unapplyメソッドを持つオブジェクトです。 unapplyメソッドは、applyメソッドの逆操作です。unapplyはオブジェクトを受け入れ、オブジェクトから値を抽出します。抽出された値は通常、オブジェクトを建築するための値です。

次の例では、電子メールアドレスのエクストラクタオブジェクトを示しています。

実例

object Test {
   def main(args: Array[String]) {
      
      println ("Apply メソッド : " + apply("me", "gmail.com"));
      println ("Unapply メソッド : " + unapply("me@gmail.com"));
      println ("Unapply メソッド : " + unapply("Zara L"));

   }
   // メソッドを記述する (オプション)
   def apply(user: String, domain: String) = {
      user +"@"+ domain
   }

   // メソッドを抽出する(必須)
   def unapply(str: String): Option[(String, String)] = {
      val parts = str split "@"
      if (parts.length == 2){
         Some(parts(0), parts(1)) 
      }else{
         None
      }
   }
}

上記のコードを実行した出力結果は次となります。

$ scalac Test.scala 
$ scala Test
Apply メソッド : me@gmail.com
Unapply メソッド : Some((me,gmail.com))
Unapply メソッド : None

上記のオブジェクトは、applyメソッドとunapplyメソッドの2つのメソッドを定義しています。 applyメソッドを使用すると、newを使用せずにオブジェクトを作成できます。したがって、 Test(“me”, “gmail.com”) ステートメントで文字列 “me@gmail.com”を作成できます。

unapplyメソッドは、applyメソッドの逆操作です。unapplyはオブジェクトを受け入れ、オブジェクトから値を抽出します。抽出された値は通常、オブジェクトを建築する値です。実例では、Unapplyメソッドを使用して、オブジェクトからユーザー名と電子メールアドレスのサフィックスを抽出します。

実例では、受けた文字列が電子メールアドレスでない場合、unapplyメソッドはNoneを返します。返す結果は次のとおりです。

unapply(“me@gmail.com”) は Some(“me”, “gmail.com”)に相当します

unapply(“Zara L”) は Noneに相当します

エクストラクタでパターンマッチングを使用する

クラスをインスタンス化するばあい、0個以上のパラメータを受け取ることができ、コンパイラはインスタンス化するときにapplyメソッドを呼び出します。クラスとオブジェクトの両方でapplyメソッドを定義できます。

前言った通りに、unapplyは、指定した検索する値を抽出するために使用されます。これは、applyの逆操作です。エクストラクタオブジェクトでmatchステートメントを使用すると、unapplyが自動的に実行されます。次には例を挙げます。

実例

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

      x match
      {
   case Test(num) => println(x + " は " + num + " の2倍です!")
         //unapply は呼ばれます
         case _ => println("計算できません")

      }

   }
   def apply(x: Int) = x*2
   def unapply(z: Int): Option[Int] = if (z%2==0) Some(z/2) else None
}

上記のコードを実行した出力結果は次となります。

$ scalac Test.scala 
$ scala Test
10
10 は 5 の2倍です
Share

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です