9
votes

Pourquoi la surcharge de la méthode n'est-elle pas définie pour différents types de retour?

in Scala, vous pouvez surcharger une méthode en ayant des méthodes qui partagent un nom commun, mais qui ont des mèches différentes ou des types de paramètres différents. Je me demandais pourquoi cela n'était pas également étendu au type de retour d'une méthode? Considérez le code suivant:

class C {
  def m: Int = 42
  def m: String = "forty two"
}

val c = new C
val i: Int = C.m
val s: String = C.m


2 commentaires

6 Réponses :


2
votes

Je n'ai jamais utilisé Scala, alors quelqu'un me frappe sur la tête si je me trompe ici, mais c'est ma prise.

Disons que vous avez deux méthodes dont les signatures diffèrent uniquement par type de retour.

Si vous appelez cette méthode, comment le compilateur (interpréteur?) Sachez quelle méthode vous souhaitez réellement appeler?

Je suis sûr que dans certaines situations, il pourrait être capable de le comprendre, mais de quoi par exemple, l'un de vos types de retour est une sous-classe de l'autre? Ce n'est pas toujours facile.

Java n'autorise pas la surcharge des types de retour, et puisque Scala est construit sur le Java JVM, il s'agit probablement d'une limitation de Java.

(éditer) Notez que les retours Covariant sont un problème différent. Lors du remplacement d'une méthode, vous pouvez choisir de retourner une sous-classe de la classe que vous êtes censé revenir, mais vous ne pouvez pas choisir une classe non liée à revenir.


0 commentaires

1
votes

Afin de différencier une fonction différente avec le même nom et les mêmes types d'arguments, mais des types de rendement différents, une syntaxe est requise ou une analyse du site d'une expression.

Scala est une langue orientée expression (chaque relevé est une expression). Généralement, les langues orientées d'expression préfèrent que la sémantique des expressions ne soit dépendante que sur l'évaluation de la portée, non ce qui arrive au résultat, donc pour l'expression foo () dans i_take_an_int (foo ()) et i_take_any_type (foo ()) et foo () comme une déclaration Tout appeler la même version de foo () .

Il y a aussi le problème que l'ajout de surcharge par type de retour à une langue avec le type inference rendra le code complètement incompréhensible - vous devez garder une quantité incroyable du système à l'esprit afin de prédire ce qui va se passer quand le code obtient exécuté.


0 commentaires

6
votes

Vous pouvez bien sûr avoir une surcharge pour des méthodes qui diffèrent par type de retour, tout comme des méthodes qui diffèrent uniquement em> par type de retour. Par exemple, c'est bien: xxx pré>

qui de côté, la réponse à votre question est évidemment qu'il s'agissait d'une décision de conception: le type de retour fait partie de la signature de méthode comme quiconque a connu une abstractmethoderror code> peut vous dire. p>

Considérez cependant comment permettre une telle surcharge pourrait fonctionner en tandem avec la sous-dactylographie: P>

class B extends A {
  def foo: String = "Hello"
}


1 commentaires

Le type statique d'A est A, et A n'a qu'une méthode appelée FOO (celle qui retourne int) alors où est l'ambiguïté?



6
votes

La principale raison concerne la complexité des problèmes: avec une approche de compilateur «normale», vous allez à l'intérieur (de l'expression intérieure à la portée extérieure), construisez votre étape binaire à pas; Si vous ajoutez une différenciation de type de retour, vous devez passer à une approche de retour en arrière, ce qui augmente considérablement l'heure de compilation, la complexité du compilateur (= bugs!).

En outre, si vous retournez un sous-type ou un type pouvant être automatiquement converti à l'autre, quelle méthode devez-vous choisir? Vous donneriez des erreurs d'ambiguïté pour un code parfaitement valide.

ne vaut pas la peine.

Dans l'ensemble, vous pouvez facilement refroidir votre code pour éviter la surcharge de type retour, par exemple en ajoutant un paramètre factice du type que vous souhaitez revenir.


0 commentaires

8
votes

En fait, vous pouvez le faire fonctionner par la magie de «implicite». Comme suit: xxx


0 commentaires

1
votes

Toutes les réponses qui disent que la JVM ne permet pas que cela soit tout droit. Vous peut forte> surcharge basé sur le type de retour. Étonnamment, le JVM fait em> le permet; Ce sont les compilateurs em> pour les langues qui fonctionnent sur la JVM qui ne le permettent pas. Mais il existe des moyens de contourner les limitations du compilateur à Scala.

Par exemple, considérez l'extrait de code suivant: p> xxx pré>

Ceci lancera une erreur de compilateur (car varargs, indiqué par le * code> après Type d'argument, type effaçable à SEQ code>): p> xxx pré>

Toutefois, si vous modifiez la valeur du second foo code> à 3 code> au lieu de bar code> (de cette façon de modifier le type de retour de chaîne code> à int code>) comme suit: p >

3
foo


0 commentaires