2013-08-20 3 views
6

я написал класс, который принимает переменное число аргументов в качестве параметра, и указать его значение по умолчанию, так что пользователь может часто его экземпляр без указания параметра:Почему невозможно указать значение по умолчанию параметра Scala varargs?

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

Однако компилятор и РЕПЛ дать мне следующие ошибки :

<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) { } 

в качестве обходного пути, я попытался следующие, но это не сработало: (. это очень неоднозначный, очевидно)

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

Интересно, почему для параметра varargs не указано значение по умолчанию. Какая здесь причина или техническая причина? (Мое предположение заключается в том, что для указания пустых varargs потребуется некоторый специальный синтаксис или идиома, но я не уверен, что это достаточная причина.)

ответ

5

Подумав немного об этом, я думаю, что это просто вопрос, не добавляя слишком много сложности, предположим, что у вас есть

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

Теперь абонент использует так: f(a).

Как мы узнаем, должен ли вызывающий объект передать нулевой список или хотел вызвать аргументы по умолчанию, не предоставив ? В вашем примере вы предполагаете, что второй вариант - единственный случай, который когда-либо будет, и что компилятор должен предоставить значение аргумента по умолчанию. Но пустой Seq() уже является вполне допустимым значением, предоставляемым вызывающим. Я предполагаю, что вызывающий может написать f(a, Seq(): _*), но это громоздко.

+0

Почему 'def foo (результат: Int = 0, xs: String *) = ???' неприемлемо? Для компилятора вполне возможно распознать 'foo (0,« невозможно компилировать »)' как законную конструкцию. –

+0

@ om-nom-nom, не уверен, что я последую за тобой.Я отвечаю, почему мы не хотим поддерживать 'def foo (результат: Int = 0, xs: String * = Seq (" some "," default ")) = ???'. – huynhjl

+0

yep, но компилятор ставит те же самые ограничения в моем случае (по крайней мере, дает нам ту же ошибку компиляции), поэтому, я думаю, может быть и другая причина, которая объединяет эти два случая –

3

Varargs, не только в Scala, является абстракцией над списком аргументов , если я не ошибаюсь, он desugared в Seq, список аргументов. Исходя из этого, какой результат вы ожидаете от values: Int* = 42? А затем, когда вы вызываете этот метод, как аргументы должны быть переданы в этот метод?

+2

Но вы можете, по крайней мере, делать 'значения: Int * = (Array (42): Int *)' – Jatin

5

Из спецификации лестницы (раздел 4.6.2)

Не разрешается определяют любые аргументы по умолчанию в разделе параметров с повторяющимся параметром

Может быть, обходной путем помочь?

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

Это не объясняет, почему это так, просто постулирует такое отрицание. –

2

Другим решением является сделать Seq явным:

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

Да, это обходной путь, с которым я столкнулся. – trustin

2

Значение по умолчанию для списков параметров просто не имеет смысла, так как вы не можете выяснить, сколько аргументы должны быть переданы. Это не ограничение scala, это логическое ограничение.

Смежные вопросы