2013-08-20 26 views
6

napisałem klasę, która akceptuje varargs jako parametr i określ jego domyślne, tak że użytkownik może często instancję bez podania parametru:Dlaczego nie jest możliwe określenie domyślnej wartości parametru varaliS Scala?

class MyClass(values: Int* = 42) { } 

Jednak kompilator i REPL dać mi następujące błędy :

<console>:7: error: type mismatch; 
found : Int(42) 
required: Int* 
     class MyClass(values: Int* = 42) { } 
           ^
<console>:7: error: a parameter section with a `*'-parameter is not allowed to have default arguments 
     class MyClass(values: Int* = 42) { } 

Jako obejście, próbowałem następujące, ale to nie działa albo: (. to bardzo niejednoznaczne oczywiście)

class MyClass(value: Int = 42, otherValues: Int*) { } 

Zastanawiam się, dlaczego nie jest dozwolone posiadanie domyślnego parametru varargs. Jakie jest rozumowanie lub powód techniczny leżący tutaj? (Domyślam się, że określenie pustych varargs wymagałoby specjalnej składni lub idiomu, ale nie jestem pewien, czy to wystarczający powód).

Odpowiedz

5

Myślenie trochę o tym, myślę, że jest to po prostu kwestia nie dodając zbyt wiele złożoności, załóżmy, że masz

def f(a: A, xs: X* = Seq(x0, x1)) = ??? 

Teraz rozmówca używa tak: f(a).

Skąd wiemy, że osoba dzwoniąca zamierzała przekazać listę zerową o wartości lub chcieć wyzwolić domyślne argumenty, nie podając ? W twoim przykładzie zakładasz, że druga alternatywa to jedyny przypadek, jaki kiedykolwiek będzie i że kompilator musi dostarczyć domyślną wartość argumentu. Ale pusty Seq() jest już doskonale poprawną wartością dostarczoną przez wywołującego. Domyślam się, że rozmówca mógł napisać f(a, Seq(): _*), ale jest to uciążliwe.

+0

Dlaczego 'def foo (wynik: Int = 0, xs: String *) = ???' jest nieakceptowane? Jest całkowicie możliwe, aby kompilator rozpoznał "foo (0," niemożliwe do kompilacji ") jako prawną konstrukcję. –

+0

@ om-nom-nom, nie jestem pewien, czy podążam za Tobą.Odpowiadam, dlaczego nie chcemy wspierać 'def foo (wynik: Int = 0, xs: String * = Seq (" some "," default ")) = ???'. – huynhjl

+0

tak, ale kompilator umieszcza to samo ograniczenie w moim przypadku (przynajmniej daje nam ten sam błąd kompilacji), więc domyślam się, że może istnieć jakiś inny powód, który unifikuje te dwa przypadki –

3

Varargs, nie tylko w Scali, jest abstrakcją na liście argumentów , Jeśli się nie mylę, to jest przytoczony do Seq, listę argumentów. Na podstawie tego, jakiego rezultatu oczekujesz od values: Int* = 42? A potem, kiedy nazwiesz tę metodę, jak argumenty powinny zostać przekazane do tej metody?

+2

Ale można co najmniej zrobić 'wartości: Int * = (Array (42): Int *)' – Jatin

5

Od specyfikacji Scala (sekcja 4.6.2)

Nie dopuszcza do de fi ne jakieś argumenty domyślne w sekcji parametr z wielokrotnym parametru

Może obejście pomógłby?

class MyClass(values: Int*) { 
    def this() = this(5) 
} 
+1

Nie wyjaśnia, dlaczego tak jest, tylko postuluje taką odmowę. –

2

Innym rozwiązaniem jest uczynić seq wyraźne:

class MyClass(values: Seq[Int] = Seq(42)) { } 
+0

Tak, to obejście, na które wpadłem. – trustin

2

domyślną wartość varargs po prostu nie ma sensu, ponieważ nie można dowiedzieć się, jak wiele argumentów powinny być przekazywane. Nie jest to ograniczenie scala, jest to logiczne ograniczenie.