Scala permite pasar funciones sin parámetros como parámetros de un método. Cuando un método así es invocado, los parámetros reales de la función enviada sin parámetros no son evaluados y una función “nularia” (de aridad cero, 0-aria, o sin parámetros) es pasada en su lugar. Esta función encapsula el comportamiento del parámetro correspondiente (comunmente conocido como “llamada por nombre”).
Para aclarar un poco esto aquí se muestra un ejemplo:
object TargetTest1 extends App {
def whileLoop(cond: => Boolean)(body: => Unit): Unit =
if (cond) {
body
whileLoop(cond)(body)
}
var i = 10
whileLoop (i > 0) {
println(i)
i -= 1
}
}
La función whileLoop
recibe dos parámetros cond
y body
. Cuando la función es llamada, los parámetros reales no son evaluados en ese momento. Pero cuando los parámetros son utilizados en el cuerpo de la función whileLoop
, las funciones nularias creadas implícitamente serán evaluadas en su lugar. Así, nuestro método whileLoop
implementa un bucle tipo Java mediante una implementación recursiva.
Es posible combinar el uso de operadores de infijo y postfijo (infix/postfix) con este mecanismo para crear declaraciones más complejas (con una sintaxis agradadable).
Aquí mostramos la implementación de una declaración tipo repetir-a-menos-que (repetir el bucle a no ser que se cumpla X condición):
object TargetTest2 extends App {
def loop(body: => Unit): LoopUnlessCond =
new LoopUnlessCond(body)
protected class LoopUnlessCond(body: => Unit) {
def unless(cond: => Boolean): Unit = {
body
if (!cond) unless(cond)
}
}
var i = 10
loop {
println("i = " + i)
i -= 1
} unless (i == 0)
}
La función loop
solo acepta el cuerpo de un bucle y retorna una instancia de la clase LoopUnlessCond
(la cual encapsula el cuerpo del objeto). Es importante notar que en este punto el cuerpo del bucle no ha sido evaluado aún. La clase LoopUnlessCond
tiene un método unless
el cual puede ser usado como un operador de infijo (infix). De esta manera podemos lograr una sintaxis muy natural para nuestro nuevo bucle repetir { <estas declaraciones> a_menos_que ( <condición>)
.
A continuación se expone el resultado de la ejecución de TargetTest2
:
i = 10
i = 9
i = 8
i = 7
i = 6
i = 5
i = 4
i = 3
i = 2
i = 1
Contributors to this page:
Contents
- Introducción
- Basics
- Tipos Unificados
- Clases
- Valores de parámetros por defecto
- Parámetros nombrados
- Traits
- Tuples
- Composición de clases mixin
- Funciones de orden superior
- Funciones Anidadas
- Currying
- Clases Case
- Reconocimiento de patrones
- Singleton Objects
- Patrones basados en expresiones regulares
- Objetos Extractores
- For Comprehensions
- Clases genéricas
- Varianzas
- Límite de tipado superior
- Límite de tipado inferior
- Clases Internas
- Tipos Abstractos
- Tipos Compuestos
- Autorefrencias explicitamente tipadas
- Parámetros implícitos
- Implicit Conversions
- Métodos polimórficos
- Inferencia de tipos Local
- Operadores
- By-name Parameters
- Anotaciones
- Packages and Imports
- Package Objects