Dadas tres formas de expresar la misma función f(a) := a + 1
:
val f1 = (a:Int) => a + 1
def f2 = (a:Int) => a + 1
def f3:(Int => Int) = a => a + 1
¿En qué se diferencian estas definiciones? El REPL no indica diferencias obvias:
scala> f1
res38: (Int) => Int = <function1>
scala> f2
res39: (Int) => Int = <function1>
scala> f3
res40: (Int) => Int = <function1>
f1
en el REPL muestra el valor vinculado estáticamente alf1
evaluarf2
yf3
muestra el resultado de invocar esos métodos. En particular,Function1[Int, Int]
se produce una nueva instancia cada vez que se invocaf2
of3
, mientras quef1
es la mismaFunction1[Int, Int]
para siempre.Respuestas:
f1
es una función que toma un número entero y devuelve un número entero.f2
es un método con aridad cero que devuelve una función que toma un número entero y devuelve un número entero. (Cuando escribef2
en REPL más tarde, se convierte en una llamada al métodof2
).f3
es lo mismo quef2
. Simplemente no está empleando la inferencia de tipos allí.fuente
f1
es unfunction
yf2
es unmethod
?apply
. Un método, bueno, es un método.f2
sí mismo no acepta argumentos. El objeto de función que devuelve lo hace.Dentro de una clase,
val
se evalúa en la inicialización, mientrasdef
que solo se evalúa cuando y cada vez que se llama a la función. En el código siguiente, verá que x se evalúa la primera vez que se usa el objeto, pero no cuando se accede al miembro x. Por el contrario, y no se evalúa cuando se crea una instancia del objeto, sino que se evalúa cada vez que se accede al miembro.fuente
a
es inmutable y se evalúa en la inicialización, perob
sigue siendo un valor mutable. Por tanto, la referencia ab
se establece durante la inicialización, pero el valor almacenado porb
permanece mutable. Para divertirse, ahora puede crear uno nuevoval b = 123
. Después de estoa(5)
, siempre dará 11, yab
que ahora es un valor completamente nuevo.La ejecución de una definición como def x = e no evaluará la expresión e . En su lugar, e se evalúa siempre que se usa x . Alternativamente, Scala ofrece una definición de valor val x = e , que evalúa el lado derecho e como parte de la evaluación de la definición. Si luego se usa x posteriormente, se reemplaza inmediatamente por el valor precalculado de e , por lo que la expresión no necesita ser evaluada nuevamente.
fuente