9

J'utilise les paramètres par défaut de Scala 2.8 sur un constructeur, et pour des raisons de compatibilité Java, je voulais un constructeur sans-argument qui utilise les paramètres par défaut.Constructeur sans no-Scala supplémentaire et paramètres de constructeur par défaut

Cela ne fonctionne pas pour des raisons très sensibles:

class MyClass(field1: String = "foo", field2: String = "bar") { 
    def this() = { 
     this() // <-- Does not compile, but how do I not duplicate the defaults? 
    } 
} 

Je me demande s'il y a quelque chose que je suis absent. Des réflexions qui ne nécessitent pas de duplication des paramètres par défaut?

Merci!

+1

il y a un ticket à https://lampsvn.epfl.ch/trac/scala/ticket/4278 –

+1

J'ai parlé en faveur de ce billet lors de ma première réunion de la scala en chair et en os et dit que la chair était consommée par vorace " ne va pas ruiner la langue avec vos cas spéciaux "loups. C'est chaque cas d'utilisation pour lui-même maintenant! – extempore

Répondre

12

Je ne recommanderais pas vraiment, mais vous pouvez le faire en ajoutant un autre paramètre à votre constructeur:

class MyClass(a: String = "foo", b: String = "bar", u: Unit =()) { 
    def this() { this(u =()) } 
} 

Unit est un bon choix parce que vous ne pouvez passer une chose en elle de toute façon, de manière explicite passer la valeur par défaut ne permet aucune possibilité d'erreur, et pourtant il vous permet d'appeler le bon constructeur.

Si vous souhaitez répliquer seulement un par défaut, vous pouvez utiliser la même stratégie sauf remplacer celle que vous avez choisie par défaut au lieu d'ajouter le paramètre unité.

+0

Je suis d'accord que c'est dans l'esprit de ma question (minimiser la duplication), mais pas une bonne pratique. Merci d'avoir répondu! – jkl

4

pirater le travail autour curieux, et je ne signifie-pirater: vous pouvez utiliser la représentation interne des arguments par défaut:

class MyClass(field1: String = "foo", field2: String = "bar") { 
    def this() = this(MyClass.init$default$1) 
} 

Notez qu'il est nécessaire d'inclure MyClass dans ce (MyClass.init $ par défaut $ 1). Une explication partielle est que les arguments par défaut sont conservés dans les objets compagnons.

4

Vous pouvez envisager d'utiliser une méthode de fabrication:

class MyClass(field1: String = "foo", field2: String = "bar") 
object MyClass { 
    def newDefaultInstance = new MyClass 
} 

Ensuite, à partir de Java vous pouvez appeler MyClass.newDefaultInstance()

Une autre possibilité est de se déplacer où vous spécifiez les valeurs par défaut:

class MyClass(field1: String, field2: String) { 
    def this() = this(field1="foo", field2="bar") 
} 

Cette Le style est particulièrement utile si vous travaillez avec un framework tel que Spring qui utilise la réflexion pour localiser un constructeur 0-arg.

+0

Merci pour les idées.Dans mon cas, le premier ne fonctionnerait pas car c'est un servlet que j'initialise (donc j'ai besoin du no-arg.) Le second est faisable, mais je perds le comportement par défaut agréable dans les tests que les valeurs par défaut fournissaient . Je me serais probablement tourné vers le premier si je n'avais pas eu besoin du constructeur no-arg ... – jkl

0

Ne convient pas à toutes fins utiles, mais une sous-classe peut faire l'affaire:

class DefaultMyClass extends MyClass() 
0

Si je ne me trompe pas dans la compréhension de la question, le code suivant très bien fonctionné pour me`

class Employee (

    ){ 
    def this(name :String , 

    eid :Int){ 
    this(); 
    } 
} 

`

Questions connexes