risposta
sovraccarico rende un po 'più difficile per sollevare un metodo per una funzione:
object A {
def foo(a: Int) = 0
def foo(b: Boolean) = 0
def foo(a: Int, b: Int) = 0
val function = foo _ // fails, must use = foo(_, _) or (a: Int) => foo(a)
}
Non si può selettivamente importare uno di una serie di metodi di overload.
V'è una maggiore probabilità che l'ambiguità si porrà quando si cerca di applicare vista impliciti per adeguare gli argomenti per i tipi di parametri:
scala> implicit def S2B(s: String) = !s.isEmpty
S2B: (s: String)Boolean
scala> implicit def S2I(s: String) = s.length
S2I: (s: String)Int
scala> object test { def foo(a: Int) = 0; def foo(b: Boolean) = 1; foo("") }
<console>:15: error: ambiguous reference to overloaded definition,
both method foo in object test of type (b: Boolean)Int
and method foo in object test of type (a: Int)Int
match argument types (java.lang.String)
object test { def foo(a: Int) = 0; def foo(b: Boolean) = 1; foo("") }
Può tranquillamente rendere parametri di default inutilizzabile:
object test {
def foo(a: Int) = 0;
def foo(a: Int, b: Int = 0) = 1
}
Individualmente, questi motivi non ti obbligano a evitare completamente il sovraccarico. Mi sento come se mi mancassero alcuni problemi più grandi.
UPDATE
L'evidenze si accumulano e.
- Si complica la spec
- Può render implicits unsuitable per l'uso in vista limiti.
- Limita l'introduzione dei valori predefiniti per i parametri solo su una delle alternative sovraccaricate.
- Poiché gli argomenti verranno digitati senza un tipo previsto, non è possibile passare a valori di funzione anonimi come '_.foo' as arguments to overloaded methods.
UPDATE 2
- non si può (al momento) utilizzare metodi in oggetti di pacchetto sovraccarico.
- Gli errori di applicabilità sono harder to diagnose per i chiamanti della propria API.
UPDATE 3
risoluzione sovraccarico statico può privare un'API di tutta sicurezza tipo:
scala> oggetto O {def applicare [T] (ts: T *) =(); def apply (f: (String => Int)) =()} oggetto definito O
scala> O ((i: String) => f (i)) // oops, intendevo chiamare il secondo sovraccarico, ma qualcuno ha cambiato il tipo di ritorno di
f
quando non stavo guardando ...
Attualmente, c'è anche un errore in scalac che viene attivato dall'overloading in alcuni casi. https://issues.scala-lang.org/browse/SI-7596. – cvogt
I primi due problemi non influiscono su ogni utilizzo valido del sovraccarico. Archiviato [un bug report] (https://issues.scala-lang.org/browse/SI-7856) per il terzo numero. La [restrizione sui valori predefiniti è per scelta] (http://stackoverflow.com/a/4652681/615784) e in teoria potrebbe essere risolta. L'errore del problema '_.foo' è l'inferenza di tipo limitata di Scala, non il sovraccarico. Rispondete alla domanda, ma alcune delle ragioni sono dovute ad altre debolezze in Scala che potrebbero essere migliorate. Il sovraccarico è più efficiente rispetto al runtime downcasting di una disgiunzione, o un prodotto cartesiano di nomi è rumoroso e si disconnette da una semantica condivisa. –
Le classi di tipi offrono in alternativa un'alternativa all'overloading. The Magnet Pattern (http://spray.io/blog/2012-12-13-the-magnet-pattern/) spinge questa idea in modi interessanti. – retronym
penso che il consiglio non è destinato a Scala in particolare, ma per OO in generale (finora so scala dovrebbe essere un best-of-breed tra le OO e funzionale).
Override va bene, è il cuore del polimorfismo ed è centrale per la progettazione OO.
Il sovraccarico di d'altra parte è più problematico. Con il sovraccarico del metodo è difficile distinguere quale metodo verrà realmente invocato ed è spesso una fonte di confusione. Raramente c'è anche una giustificazione per cui il sovraccarico è davvero necessario. Il problema può essere risolto per la maggior parte del tempo in un altro modo e concordo sul fatto che il sovraccarico è un odore.
Ecco lo an article che spiega bene ciò che intendo con "sovraccarico è fonte di confusione", che ritengo sia il motivo principale per cui è scoraggiato. È per java, ma penso che valga anche per scala.
E Scala isn in primis un linguaggio OO –
@ewernli: questo è un link utile Modifica la tua risposta per includere questo link e ti invierò in anticipo – missingfaktor
@ewenli - Jorge è ben noto nella comunità scala e il link che Rahul ha fornito era uno dei consigli di scala di Jorge, ma la tua risposta non ha nulla da offrire sul perché il sovraccarico è cattivo * specificamente per scala *, che era chiaramente l'intento della domanda.Inoltre, non ho idea del motivo per cui hai deciso che la domanda era in qualche modo confusa - dovresti semplicemente rimuoverlo dalla tua risposta dato che è totalmente ingiustificato. -1 –
le ragioni che Gilad e Jason (retronym) danno sono tutti ottimi motivi per evitare di sovraccaricare se possibile. Le ragioni di Gilad si concentrano sul perché il sovraccarico è problematico in generale, mentre le ragioni di Jason si concentrano sul perché è problematico nel contesto di altre funzionalità di Scala.
Per la lista di Jason, vorrei aggiungere che l'overloading interagisce male con l'inferenza di tipo. Considerare:
val x = ...
foo(x)
Un cambiamento del tipo derivato di x
che potrebbe alterare foo
metodo viene chiamato. Il valore di x
non deve essere modificato, solo il tipo di x
dedotto, che potrebbe verificarsi per tutti i tipi di motivi.
Per tutti i motivi indicati (e alcuni altri sono sicuro che mi sto dimenticando), penso che il sovraccarico di metodo dovrebbe essere usato con la massima parsimonia possibile.
Se non vuoi che ciò accada, dichiari il tipo per x. Se non lo dichiari, allora stai dicendo che desideri che cambi. La semantica di 'pippo' dovrebbe essere la stessa per ogni sovraccarico con lo stesso numero di parametri, altrimenti è stata progettata in modo errato. Per quanto riguarda la limitazione dell'ambito della bizzarra cascata di modifiche di inferenza, i metodi pubblici dovrebbero sempre dichiarare i loro tipi di ritorno. Penso che questo sia uno dei problemi che riguardano la compatibilità binaria di Scala tra le versioni. –
Potrebbe avere qualcosa a che fare con il fatto che Scala eredita la cancellazione del tipo di Java? –
@Justin: che cosa ha a che fare questo tipo di cancellazione del carattere? – missingfaktor
Perché non chiedi a Jorge Ortiz perché si sconsiglia di sovraccaricare il metodo? – John