2010-10-28 20 views
9

Sto utilizzando i parametri di default di Scala 2.8 su un costruttore e, per ragioni di compatibilità Java, volevo un costruttore no-arg che utilizza i parametri predefiniti.Scala extra no-arg costruttore più parametri predefiniti costruttore

Questo non funziona per ragioni molto sensibili:

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

Mi chiedo se c'è qualcosa che mi manca. Qualsiasi pensiero che non richieda la duplicazione dei parametri predefiniti?

Grazie!

+1

c'è un biglietto su https://lampsvn.epfl.ch/trac/scala/ticket/4278 –

+1

Ho parlato a favore di quel biglietto al mio primo incontro di scala in carne e ho detto che la carne era consumata da famelico " non andare a rovinare la lingua con i tuoi casi speciali "lupi. È ogni caso d'uso per se stesso ora! – extempore

risposta

12

non mi sarebbe davvero consiglio, ma lo si può fare con l'aggiunta di un altro parametro al costruttore:

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

Unit è una buona scelta, perché si può passare solo una cosa in esso comunque, in modo esplicito il passaggio del valore predefinito non consente alcuna possibilità di errore e tuttavia consente di chiamare il costruttore corretto.

Se si è disposti a replicare solo uno dei valori predefiniti, è possibile utilizzare la stessa strategia tranne eseguire l'override di un valore predefinito scelto anziché aggiungere il parametro unità.

+0

Sono d'accordo che questo è nello spirito della mia domanda (riducendo al minimo la duplicazione), ma non è una grande pratica. Grazie per la risposta! – jkl

4

curioso work-around hack, e lo faccio significa incidere: è possibile utilizzare la rappresentazione interna di argomenti di default:

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

Si noti che è necessario includere MyClass in questo (MyClass.init $ default $ 1). Una spiegazione parziale è che gli argomenti predefiniti sono conservati negli oggetti associati.

4

Si potrebbe considerare l'utilizzo di un metodo di fabbrica:

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

Poi da Java è possibile chiamare MyClass.newDefaultInstance()

Un'altra possibilità è quella di spostare in cui si specificano i valori di default:

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

Questo lo stile è particolarmente utile se si lavora con un framework come Spring che usa la reflection per localizzare un costruttore di 0-arg.

+0

Grazie per le idee.Nel mio caso esatto, il primo non funzionerebbe in quanto si tratta di un servlet che sto iniziando (quindi ho bisogno del no-arg.) Il secondo è fattibile, ma perdo il piacevole comportamento di default nei test che i valori predefiniti stavano fornendo . Sarei probabilmente passato al primo se non avessi avuto bisogno del costruttore no-arg ... – jkl

0

Non adatto a tutti gli effetti, ma una sottoclasse potrebbe fare il trucco:

class DefaultMyClass extends MyClass() 
0

Se non sbaglio nel capire la questione, seguente codice ha funzionato molto bene per me`

class Employee (

    ){ 
    def this(name :String , 

    eid :Int){ 
    this(); 
    } 
} 

`

Problemi correlati