I'm trying to understand the crucial difference between these two approaches of referencing / defining Function Literal
(reference to anonymous function
):
By val
scala> val v2 = new Function[Int, Int] {
| def apply(a: Int): Int = a + 1
| }
v2: Int => Int = <function1>
And by def
scala> def f2 = new Function[Int, Int] {
| def apply(a: Int): Int = a + 1
| }
f2: Int => Int
It seems that it pretty much the same in terms of use. I either can pass v2
or f2
to the function that accepts (Int) => Int
as an argument. Passing arguments to its..
I guess or the case of v2 it creates an Function1
object that refers to the Function1
object.. like a proxy
?
Ok.. My question is: what is advantage and disadvantages of 1th and 2nd approach?
And of it is defined by def
, is it still Function Literal
?
First of all, neither of your examples are actually function literals—you're creating a
Function
instance in the plain old sugar-free way, and in fact you could use this approach (new Function { ... }
) to create an instance ofscala.Function
from Java code.The following are both function literals, and are exactly equivalent to your definitions:
The only real difference here is that the
val
will create a single instance once and for all, no matter how many times you usev2
(and even if you never use it), while thedef
will create a new instance every time (or not at all, if you never use it). So you'll generally want to go with aval
.There are cases, however, where you need to use
def
. Consider the following:There's no way we could write this as a
val
, since Scala doesn't have polymorphic functions in this sense (for any instance ofFunction[A, B]
,A
andB
have to be concrete types). But we can define a polymorphic method that returns a function, and when we write e.g.myIndentity(1)
, theA
will be inferred to beInt
, and we'll create (and apply) aFunction[Int, Int]
exactly as you'd expect.