2010-10-10 5 views
13

Mam zdefiniowane wiele konstruktorów, z niektórymi domyślnymi wartościami argumentów we wszystkich z nich. Wygląda na prawidłowe (nie widzę żadnej dwuznaczności), ale Scala (2.8) kompilator narzeka:Nie mogę zdefiniować wartości domyślnych, jeśli zdefiniuję wiele przeciążonych konstruktorów w Scali?

multiple overloaded alternatives of constructor define default arguments

Czy to znaczy, że nie można określić wartości domyślne dla konstruktorów przeładowanych w ogóle?

Pozwól mi ilustrują sytuację (primitivized, oczywiście, ale ilustracyjne):

 

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

Czy mógłbyś zamieścić w tym swój kod? –

Odpowiedz

9

wyjęta prosto z kodu źródłowego kompilatora:

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

W ogóle, nie radzę, że mieszasz przeciążenia i ustawienia domyślne. Nawet jeśli nie ma konfliktu, może to utrudnić odczytanie kodu.

UPDATE

Ponieważ kod dodaje, to jasne, że teraz nie chcą/muszą przesłonić domyślne wartości dla każdego konstruktora wtórnym. W twoim konkretnym przypadku mógłbym nawet kwestionować zapotrzebowanie na tych dodatkowych konstruktorów; Int => Double jest już dostępna dla ciebie jako niejawna konwersja, a String => Double wygląda na to, że możesz perwersjonować system typów :)

Również ... Jako alternatywa dla przeciążonych konstruktorów, możesz zdefiniować tylko podstawowe konstruktor z wartościami domyślnymi, a następnie przeciąż metodę apply obiektu towarzyszącego i użyj go jako fabryki. Jest to oczywiście całkowicie opcjonalne, ale szybko staje się ustalone jako wzór za pomocą klas przypadków.

+0

Korzystanie z fabryk wydaje się w tym przypadku niepotrzebne i narusza brzytwę Ockhama. Byłoby jeszcze ładniej zaimplementować konstruktory dla wszystkich przypadków (ręcznie stosując wartości domyślne) IMHO, i tak zrobiłem (wygląda zbyt oldie i samo-powtarzalne). – Ivan

+0

Zerknęłabym na mój kod, jeśli potrzebowałbym tych ilości konstruktorów. Obecnie nie potrzebuję ani jednego ... – soc

+0

Proszę, nie przejmujcie się tą odpowiedzią, aby zatwierdzić ograniczenie tego języka. – FLGMwt

4

Przeciążanie nie powiodło się, ponieważ (nieumyślnie) zdefiniowano wiele konstruktorów z wartościami domyślnymi. Zrób to zamiast tego:

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

Ale czy w tym przypadku nie należy podawać argumentów factor i doItRight, jeśli obiekt Int lub String? – Ivan

+0

Są domyślne? – soc

+0

@Ivan, Nie, nie musisz ich określać, ponieważ już ustawiłeś dla nich domyślne wartości w głównym konstruktorze. –

Powiązane problemy