Embora possa haver casos válidos em que essas sobrecargas de método possam se tornar ambíguas, por que o compilador desaprova o código que não é ambíguo no tempo de compilação nem no tempo de execução?
Exemplo:
// 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 ...
Existem razões pelas quais essas restrições não podem ser um pouco mais flexíveis?
Especialmente ao converter códigos Java altamente sobrecarregados em argumentos padrão do Scala, é muito importante e não é bom descobrir após a substituição de muitos métodos Java por um método Scala que o spec / compiler impõe restrições arbitrárias.
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");}
Respostas:
Gostaria de citar Lukas Rytz ( daqui ):
Uma solução para a versão futura do Scala poderia ser incorporar nomes de tipo dos argumentos não padrão (aqueles no início de um método, que desambiguam versões sobrecarregadas) no esquema de nomenclatura, por exemplo, neste caso:
seria algo como:
Alguém disposto a escrever uma proposta SIP ?
fonte
A with B
, por exemplo?Seria muito difícil obter uma especificação legível e precisa para as interações da sobrecarga de resolução com argumentos padrão. Obviamente, para muitos casos individuais, como o apresentado aqui, é fácil dizer o que deve acontecer. Mas isso não é suficiente. Precisávamos de uma especificação que decida todos os casos de canto possíveis. A resolução de sobrecarga já é muito difícil de especificar. A adição de argumentos padrão no mix tornaria ainda mais difícil. Por isso, optamos por separar os dois.
fonte
Não consigo responder à sua pergunta, mas aqui está uma solução alternativa:
Se você tiver duas listas de argumentos muito longas que diferem em apenas um argumento, pode valer a pena ...
fonte
Either
e não apenas afoo
- dessa maneira, sempre que umEither[A, B]
valor é solicitado, ambosA
eB
são aceitos. Em vez disso, deve-se definir um tipo que seja aceito apenas por funções com argumentos padrão (comofoo
aqui), se você quiser ir nessa direção; é claro, fica ainda menos claro se essa é uma solução conveniente.O que funcionou para mim é redefinir (no estilo Java) os métodos de sobrecarga.
Isso garante ao compilador qual resolução você deseja de acordo com os parâmetros presentes.
fonte
Aqui está uma generalização da resposta @Landei:
O que você realmente quer:
Solução alternativa
fonte
Um dos cenários possíveis é
O compilador ficará confuso sobre qual chamar. Na prevenção de outros perigos possíveis, o compilador permitiria no máximo um método sobrecarregado ter argumentos padrão.
Apenas meu palpite :-)
fonte
Meu entendimento é que pode haver colisões de nomes nas classes compiladas com valores de argumento padrão. Eu vi algo nesse sentido mencionado em vários tópicos.
A especificação do argumento nomeado está aqui: http://www.scala-lang.org/sites/default/files/sids/rytz/Mon,%202009-11-09,%2017:29/named-args.pdf
Afirma:
Então, por enquanto, de qualquer forma, não vai funcionar.
Você pode fazer algo parecido com o que você pode fazer em Java, por exemplo:
fonte