En Scala, si defino un método llamado apply
en una clase o un objeto de nivel superior, ese método se llamará cada vez que agregue un par de paréntesis a una instancia de esa clase y coloque los argumentos apropiados apply()
entre ellos. Por ejemplo:
class Foo(x: Int) {
def apply(y: Int) = {
x*x + y*y
}
}
val f = new Foo(3)
f(4) // returns 25
Básicamente, object(args)
es solo azúcar sintáctico para object.apply(args)
.
¿Cómo Scala realiza esta conversión?
¿Hay una conversión implícita definida globalmente aquí, similar a las conversiones de tipo implícitas en el objeto Predef (pero de diferente tipo)? ¿O es una magia más profunda? Lo pregunto porque parece que Scala favorece fuertemente la aplicación consistente de un conjunto más pequeño de reglas, en lugar de muchas reglas con muchas excepciones. Esto inicialmente me parece una excepción.
Respuestas:
No creo que haya nada más profundo que lo que dijiste originalmente: es simplemente azúcar sintáctico en el que el compilador se convierte
f(a)
enf.apply(a)
un caso de sintaxis especial.Esto puede parecer una regla específica, pero solo algunas de ellas (por ejemplo, con
update
) permiten construcciones y bibliotecas similares a DSL .fuente
f
es un objeto (incluidas las funciones)". Cuandof
es un método, obviamente no existe tal traducción.f
es un método que se define sin una lista de parámetros, entoncesf(a)
se interpreta como algo asíval _tmp = f; _tmp.apply(a)
. Pero eso es realmente entrar firmemente en el territorio de la división de los pelos.En realidad, es al revés, un objeto o clase con un método de aplicación es el caso normal y una función es una forma de construir implícitamente un objeto del mismo nombre con un método de aplicación. En realidad, cada función que defina es un subobjeto del rasgo Función n (n es el número de argumentos).
Consulte la sección 6.6: Aplicaciones de funciones de la especificación del lenguaje Scala para obtener más información sobre el tema.
fuente
Si. Y esta regla pertenece a este grupo más pequeño.
fuente