scala - def - ¿Por qué no puede estar implícita la primera lista de parámetros de una clase?
scala implicit conversion types (2)
scala> class A(implicit a: Int);
defined class A
scala> class B()(implicit a: Int);
defined class B
scala> new A()(1)
res1: A = A@159d450
scala> new B()(1)
res2: B = B@171f735
scala> new A(1)
<console>:7: error: too many arguments for constructor A: ()(implicit a: Int)A
new A(1)
¿Por qué Scalac inserta una lista de parámetros vacía antes de la lista de parámetros implícita proporcionada en la declaración de clase?
Esto parece ser una característica, no un error, a juzgar por el comentario en las fuentes de Scalac :
// convertir (implícito ...) a () (implícito ...) si es la única sección de parámetros
Tengo curiosidad por saber por qué se hace esto. Lo encuentro bastante sorprendente.
Bien, con la ayuda de la answer de @venechka, creo que lo he descubierto.
Con las clases ordinarias, Scala deduce y la lista de parámetros vacía, ya sea en la declaración de clase ( class B
) o en el punto de instanciación de clase ( new A
y new B
):
scala> class A()
defined class A
scala> new A
res19: A = A@12cdd20
scala> new A()
res20: A = A@1c37b8f
scala> class B
defined class B
scala> new B
res21: B = B@12801c5
scala> new B()
res22: B = B@79a340
Para mantener este principio, infiere una lista de parámetros vacía antes de una lista de parámetros implícita ( class D(implicit ...)
).
scala> class C()(implicit a: Int = 0)
defined class C
scala> new C
res23: C = C@9d1714
scala> new C()
res24: C = C@b38dba
scala> new C()(0)
res25: C = C@1677979
scala> class D(implicit a: Int = 0)
defined class D
scala> new D
res26: D = D@1a0d111
scala> new D()
res27: D = D@14e3372
scala> new D()(0)
res28: D = D@1609872
La forma en que lo veo es que la lista de parámetros implícitos no reemplaza la (s) regular (es). Dado que para las definiciones de constructores se necesita al menos una lista de parámetros, si no se indica nada explícitamente, se genera ''()''.
Si bien esto puede ser realmente sorprendente, está en línea con la generación de un constructor vacío cuando no hay listas de parámetros en absoluto.