2010-10-10 22 views
13

J'ai défini plusieurs constructeurs, avec des valeurs d'argument par défaut dans chacun d'eux. Semble correcte (je ne vois pas d'ambiguïté), mais le compilateur Scala (2.8) se plaint:Impossible de définir des valeurs par défaut si je définis plusieurs constructeurs surchargés dans Scala?

multiple overloaded alternatives of constructor define default arguments

Est-ce que cela signifie que je ne peux pas définir des valeurs par défaut pour les constructeurs surchargées à tous?

Permettez-moi d'illustrer la situation (primitivized, bien sûr, mais à titre indicatif):

 

class A(subject : Double, factor : Int = 1, doItRight : Boolean = true) { 

    def this (subject : Int, factor : Int = 1, doItRight : Boolean = true) = { 
    this(subject.toDouble , factor, doItRight) 
    } 

    def this (subject : String, factor : Int = 1, doItRight : Boolean = true) = { 
    this(subject.toDouble , factor, doItRight) 
    } 

    def this() = { 
    this(defaultSubject) 
    } 

} 


 
+1

Pourriez-vous poster le code que vous avez avec cela? –

Répondre

9

pris directement à partir du code source du compilateur: Je ne

// only one overloaded alternative is allowed to define default arguments 

En général, conseiller que vous mélangez la surcharge et les valeurs par défaut. Même s'il n'y a pas de conflit, cela peut rendre votre code plus difficile à lire.

MISE À JOUR

Depuis que vous avez ajouté le code, il est clair maintenant que vous ne voulez pas/besoin de remplacer les valeurs par défaut pour chaque constructeur secondaire. Dans votre cas particulier, je pourrais même remettre en question le besoin de ces constructeurs supplémentaires; Int => Double est déjà disponible pour vous en tant que conversion implicite et String => Double semble que vous pourriez pervertir le système de type :)

Aussi ... Comme alternative aux constructeurs surchargés, vous pouvez définir seulement le primaire constructeur avec des valeurs par défaut, puis surcharger la méthode apply de l'objet compagnon et l'utiliser comme une fabrique. Ceci est bien sûr tout à fait facultatif, mais il devient rapidement un modèle grâce à l'utilisation de classes de cas.

+0

En utilisant des usines semble assez inutile dans le cas, et violant le rasoir d'Occam. Il serait encore plus joli de mettre en œuvre des constructeurs pour tous les cas (manuellement en appliquant des valeurs par défaut) à mon humble avis, et j'ai donc fait (semble trop oldie et auto-répétant cependant). – Ivan

+0

Je regarderais attentivement mon code, si j'avais besoin de ces quantités de constructeurs. J'ai à peine besoin d'un seul ces jours-ci ... – soc

+0

S'il vous plaît ne prenez pas mon upvote de cette réponse pour signifier que j'approuve cette limitation de la langue. – FLGMwt

4

La surcharge échoue car vous définissez (sans le vouloir) plusieurs constructeurs avec des valeurs par défaut. Pour ce faire:

class A(subject : Double, factor : Int = 1, doItRight : Boolean = true) { 

    def this (subject : Int) = { 
    this(subject.toDouble) 
    } 

    def this (subject : String) = { 
    this(subject.toDouble) 
    } 

    def this() = { 
    this(defaultSubject) 
    } 
} 
+0

Mais ne pas factoriser et les arguments doItRight doivent être explicitement spécifiés si le sujet Int ou String dans ce cas? – Ivan

+0

Ils sont par défaut? – soc

+0

@Ivan, Non, vous n'avez pas besoin de les spécifier, car vous avez déjà défini leurs valeurs par défaut dans le constructeur principal. –