Si bien puede haber casos válidos en los que tales sobrecargas de métodos podrían volverse ambiguas, ¿por qué el compilador no permite el código que no es ambiguo en el momento de la compilación ni en el tiempo de ejecución?
Ejemplo:
// This fails:
def foo(a: String)(b: Int = 42) = a + b
def foo(a: Int) (b: Int = 42) = a + b
// This fails, too. Even if there is no position in the argument list,
// where the types are the same.
def foo(a: Int) (b: Int = 42) = a + b
def foo(a: String)(b: String = "Foo") = a + b
// This is OK:
def foo(a: String)(b: Int) = a + b
def foo(a: Int) (b: Int = 42) = a + b
// Even this is OK.
def foo(a: Int)(b: Int) = a + b
def foo(a: Int)(b: String = "Foo") = a + b
val bar = foo(42)_ // This complains obviously ...
¿Hay alguna razón por la cual estas restricciones no se pueden aflojar un poco?
Especialmente cuando la conversión de código Java muy sobrecargado a argumentos predeterminados de Scala es muy importante y no es bueno descubrir después de reemplazar muchos métodos Java por uno de los métodos Scala que el compilador / especificación impone restricciones arbitrarias.
object Test { def a[A](b: Int, c: Int, d: Int = 7): Unit = {}; def a[A](a:String, b: String = ""): Unit = {}; a(2,3,4); a("a");}
Respuestas:
Me gustaría citar a Lukas Rytz (desde aquí ):
Una solución para la futura versión de Scala podría ser incorporar nombres de tipo de los argumentos no predeterminados (los que se encuentran al comienzo de un método, que desambigua las versiones sobrecargadas) en el esquema de nombres, por ejemplo, en este caso:
sería algo como:
Alguien dispuesto a escribir una propuesta SIP ?
fuente
A with B
, ¿por ejemplo?Sería muy difícil obtener una especificación legible y precisa para las interacciones de la resolución de sobrecarga con argumentos predeterminados. Por supuesto, para muchos casos individuales, como el presentado aquí, es fácil decir qué debería suceder. Pero eso no es suficiente. Necesitaríamos una especificación que decida todos los casos de esquina posibles. La resolución de sobrecarga ya es muy difícil de especificar. Agregar argumentos predeterminados en la mezcla lo haría aún más difícil. Es por eso que hemos optado por separar los dos.
fuente
No puedo responder a su pregunta, pero aquí hay una solución alternativa:
Si tiene dos listas arg muy largas que difieren en un solo argumento, podría valer la pena ...
fuente
Either
y no sólo parafoo
- de esta manera, cada vez que unaEither[A, B]
se solicita el valor, tantoA
yB
son aceptadas. En su lugar, se debe definir un tipo que solo sea aceptado por las funciones que tienen argumentos predeterminados (comofoo
aquí), si desea ir en esta dirección; por supuesto, queda aún menos claro si esta es una solución conveniente.Lo que funcionó para mí es redefinir (estilo Java) los métodos de sobrecarga.
Esto garantiza al compilador la resolución que desea de acuerdo con los parámetros actuales.
fuente
Aquí hay una generalización de la respuesta de @Landei:
Lo que realmente quieres:
Workarround
fuente
Uno de los posibles escenarios es
El compilador estará confundido sobre a quién llamar. Para evitar otros posibles peligros, el compilador permitiría que, como máximo, un método sobrecargado tenga argumentos predeterminados.
Solo mi suposición :-)
fuente
Tengo entendido que puede haber colisiones de nombres en las clases compiladas con valores de argumento predeterminados. He visto algo en este sentido mencionado en varios hilos.
La especificación del argumento nombrado está aquí: http://www.scala-lang.org/sites/default/files/sids/rytz/Mon,%202009-11-09,%2017:29/named-args.pdf
Afirma:
Entonces, por el momento, en cualquier caso, no va a funcionar.
Podría hacer algo como lo que podría hacer en Java, por ejemplo:
fuente