Topic | Operator as Functions and Object as Functions |
---|---|
Git sample | OperatorsAreMethods.scala ObjectExtractorTest.scala |
References | docs.scala-lang.org java-lang.org blog.jayway.com danielwestheide.com |
Operators as Functions
Unlike Java, you can treat operators as functions (operator overloading) in Scala
Every value in Scala is an Object and every operation is a Method Call. For example, when you say
1 + 2
in Scala, you are actually invoking a method named+
defined in class Int, and 1 and 2 are objects we are passing to this methodAll operators do the usual work (
+ - * / % & | ^ >> <<
), but these operators are methods, which is owing to operator overloading feature of Scalaa + b
is a shorthand fora.+(b)
If a & b are type of Int, method '+' of Int class will applied on operation:
a.+(b)
Objects as Functions with the help of apply
and unapply
methods
Scala provides
apply
andunapply
. Methodsapply
andunapply
are not opposites of each other. Indeed, if you define one on a class/object, you don't have to define the otherMethod
apply
is probably the easier to explain. When you treat your object like a function, apply is called, so Scala turnsobj(a, b, c)
toobj.apply(a, b, c)
/* Various ways to create customer id from customer name */
object CustomerId {
/* Apply method helps in constructor calls */
def apply(name: String) = "ID-" + name
def apply(id: Int) = id
def apply(id: Long) = id.intValue
def apply(id: Double) = id.intValue
}
/* Object as function */
/* Will call 'apply(name: String)' */
println(CustomerId("Amit"))
/* Will call 'apply(id: Int)' */
println(CustomerId(100))
/* Will call 'apply(id: Long)' */
println(CustomerId(100L))
/* Will call 'apply(id: Double)' */
println(CustomerId(1000.0)
- The
apply
method takes some arguments and yields an element of a given set. This method is called an Injector - The
unapply
method is called Extractor because it takes an element of the same set and extracts some of its parts
object IPAddress {
/* The 'apply' method takes some arguments and yields an element of a given set. This method is called an injection */
def apply(a: String, b: String, c: String, d: String): String = a + "." + b + "." + c + "." + d
/* The 'unapply' method is called extractor because it takes an element of the same set and extracts some of its parts */
def unapply(ip: String): Option[(String, String, String, String)] = {
val tokens = ip split "\\."
if (tokens.length == 4 && isValid(tokens)) Some(tokens(0), tokens(1), tokens(2), tokens(3)) else None
}
}
object ObjectExtractorTest extends App {
/* Different types of ip addresses */
val ip = "127.0.0.1"
val nonIP = "128.-112.ABC."
/* Pattern matching calls 'IPAddress.unapply(ip)' */
ip match {
case IPAddress(_, _, _, a) => println(a)
case _ => println("Invalid ip address")
}
/* Pattern matching calls 'IPAddress.unapply(nonIP)' */
nonIP match {
case IPAddress(_, _, _, a) => println(a)
case _ => println("Invalid ip address")
}
}