Wednesday 20 December 2017

Scala apply and unapply



apply and unapply are the special methods in Scala. The apply method works like a constructor. Unapply uses to extract the object. The unapply method used for pattern matching.

In another word, we also call them extractor.

package scala.practice

/**  * Created by prashant on 19/12/17.  */object Foo {

  def apply(maths:Int, science:Int): Int ={
      println("I am from apply method")
      maths+science
  }

  def unapply(maths: Int): Option[String] ={
    println("I am from unapply method")
    if(maths> 40) Some("Passed") else None
  }

  def main(args: Array[String]): Unit = {
    val fooObj = Foo(10,10); //I am in apply method
//   val Foo(res) = fooObj;

//    println("Res: "+ res)  // This will cause matcherror.
    fooObj match {
      case Foo(res) => println("Test Passed") //This line will call a unapply method.

      case _ => println("Test failed")
    }
  }

}


apply and unapply need not be opposite to each other.

apply is simple, Whenever we call Object(a,b,c) it internally calls Object.apply(a,b,c). The apply method can have zero or more parameter.

The unapply method is a bit complicated!

    val fooObj = Foo(10,10); //I am in apply method   //Line 1 

    //val Foo(res) = fooObj;   //Line 2 

in line number 2, Scala compiler executing unapply method.  It internally calls,
   val res =Foo.unapply(fooObj).get

Unapply method return type could be boolean or Optional.

The unapply method CAN NOT HAVE MORE THAN ONE PARAMETER, IT SHOULD ALWAYS HAVE SINGLE PARAMETER.

The reason behind that,

 fooObj match {
      case Foo(res) => println("Test Passed") //This line will call a unapply method.      case _ => println("Test failed")
    }


In above code, fooObj is an input parameter for an unapply method, We can not match more than one parameter so unapply never have multiple parameters. If there is no match, It will throw  "scala.MatchError"  error.

In above code as unapply method return None, which matches with "case_ =>", so it does not throw any error.

//    val Foo(res) = fooObj;   //Line 2 

In above code result "None" does not match So It throws an error.

Summary: apply method used to CONSTRUCT the object and unapply used to extract the object.


No comments:

Post a Comment