9

Używam domyślnych parametrów Scala 2.8 na konstruktorze, a ze względu na kompatybilność z Javą, chciałem konstruktora no-arg, który używa domyślnych parametrów.Scala dodatkowy konstruktor no-arg oraz domyślne parametry konstruktora

To nie działa ze względu na bardzo rozsądne:

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

Zastanawiam się, czy jest coś, co mi brakuje. Wszelkie przemyślenia, które nie wymagają powielania parametrów domyślnych?

Dzięki!

+1

jest bilet na https://lampsvn.epfl.ch/trac/scala/ticket/4278 –

+1

Przemówiłem za tym biletem na moim pierwszym spotkaniu w scala ciała i powiedziałem, że ciało zostało skonsumowane przez wygłodniały " nie rujnuj języka swoimi szczególnymi przypadkami "wilkami". To teraz każdy przypadek użycia dla siebie! – extempore

Odpowiedz

12

Naprawdę nie polecam, ale można to zrobić dodając kolejny parametr do konstruktora:

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

Unit jest dobrym wyborem, ponieważ można przekazać tylko jedną rzecz do niego tak, tak wyraźnie podanie wartości domyślnej nie dopuszcza żadnej możliwości błędu, a mimo to pozwala wywołać prawidłowy konstruktor.

Jeśli chcesz zreplikować tylko jeden z domyślnych, możesz użyć tej samej strategii, z wyjątkiem zastąpienia tej wybranej domyślnej zamiast dodawania parametru jednostki.

+0

Zgadzam się, że jest to zgodne z duchem mojego pytania (minimalizacja duplikacji), ale nie jest to świetna praktyka. Dziękuję za odpowiedź! – jkl

4

Jako ciekawy obejście siekać, a ja znaczy włamać: można korzystać z wewnętrznej reprezentacji domyślne argumenty

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

Zauważ, że jest to potrzebne w celu włączenia MojaKlasa w ten (MyClass.init $ default $ 1). Częściowe wyjaśnienie jest takie, że domyślne argumenty są przechowywane w obiektach towarzyszących.

4

Można rozważyć przy użyciu metody fabryki:

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

Następnie z Java można nazwać MyClass.newDefaultInstance()

Inną możliwością jest, aby przenieść gdzie można określić wartości domyślne:

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

ten Styl jest szczególnie użyteczny, jeśli pracujesz z frameworkiem takim jak Spring, który używa refleksji do zlokalizowania konstruktora 0-arg.

+0

Dzięki za pomysły.W moim przypadku pierwszy nie zadziałałby, ponieważ jest to Servlet, który inicjuję (więc potrzebuję nie-arg). Drugi jest możliwy, ale tracę przyjemne, domyślne zachowanie w testach, które zapewniały wartości domyślne. . Prawdopodobnie zwróciłbym się do pierwszego, gdybym nie potrzebował konstruktora no-arg ... – jkl

0

Nie nadaje się do wszystkich celów, ale podklasą może załatwić sprawę:

class DefaultMyClass extends MyClass() 
0

Jeśli się nie mylę w zrozumieniu pytanie, następujący kod działa bardzo dobrze dla me`

class Employee (

    ){ 
    def this(name :String , 

    eid :Int){ 
    this(); 
    } 
} 

`

Powiązane problemy