Как должны Scala аргументы по умолчанию ссылаться на предыдущий аргумент позиции?
Scala -lang ссылка 5.5.1 и 6.6.1 дала мне впечатление, что параметр по умолчанию может ссылаться на ранее оцененный:
class Test(val first: String, val second: String = first)
но, экспериментируя, кажется, единственный способ сделать это - использовать форму:
class Test(val first: String)(val second: String = first)
а затем определите вспомогательный конструктор или класс сопутствующих сокетов, чтобы избежать указания второго набора скобок при создании. Я действительно не понимаю, как работает этот второй конструктор, он выглядит как карри-функция, поэтому я могу предположить, что нужно оценивать first
независимо от second
, это правильно? Является ли эта форма необходимой или есть какой-то синтаксический сахар, который я могу использовать, чтобы настроить первый конструктор на то, что я хочу?
Ответы
Ответ 1
Как Тревис Браун указывает, что вы действительно можете ссылаться только на предыдущий аргумент в выражении по умолчанию, когда он из предыдущего списка аргументов (так что вам нужно currify).
Теперь, в отношении вашего конкретного случая использования, аргументы по умолчанию и перегрузка метода иногда являются двумя способами достижения одного и того же.
Я думаю, что самым простым решением для вашего сценария является просто определение Test
следующим образом:
class Test(val first : String, val second : String) {
def this(f : String) = this(f, f)
}
Если вы хотите сделать его более сложным, альтернативный способ, используя сопутствующий объект:
class Test(val first : String)(val second : String = first)
object Test {
def apply(f : String) = new Test(f)
def apply(f : String, s : String) = new Test(f)(s)
}
(Небольшое различие заключается в том, что теперь вы создаете объекты без new
.)
То, что вы не можете, определяет его как:
class Test(val first : String)(val second : String = first) {
def this(f : String, s : String) = this(f)(s)
}
... потому что версия в карри превращается в (среди прочего) метод с той же сигнатурой, что и перегруженный конструктор.
Ответ 2
Из 5.3 спецификация:
Объем параметра формального значения включает все последующие секции параметров и шаблон t.
Обычные методы одинаковы, кстати (из 4.6):
Объем имени формального значения x содержит все последующие параграфы параметров, а также тип возвращаемого метода и тело функции, если они заданы.
I.e., есть ли у вас конструктор или обычный метод, имя параметра значения не входит в сферу действия в свой собственный параметр параметра. В вашей второй версии конструктор имеет два предложения параметров, а first
- только в области во втором. См. 5.3 для более подробной информации о нескольких параметрах.