Как аргументы по умолчанию Scala должны ссылаться на предыдущий позиционный аргумент?
Scala-Lang reference 5.5.1 и 6.6.1 дали мне впечатление, что параметр по умолчанию может ссылаться на ранее оцененный:
class Test(val first: String, val second: String = first)
но из экспериментов кажется, что единственный способ сделать это-использовать форму:
class Test(val first: String)(val second: String = first)
а затем определите вспомогательный конструктор или класс creational companion, чтобы избежать указания второго набора скобок при создании. Я действительно не понимаю, как работает этот второй конструктор, он выглядит как функция Карри поэтому я мог бы догадаться, что необходимо оценить first
независимо от second
, это правильно? Нужна ли эта форма или есть какой-то синтаксический сахар, который я могу использовать, чтобы настроить первый конструктор на то, что я хочу?
2 ответов
As Трэвис Браун указывает, что вы действительно можете ссылаться только на предыдущий аргумент в выражении по умолчанию, когда он из предыдущего списка аргументов (поэтому вам нужно 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
.)
что ты не может do, определяет его как:
class Test(val first : String)(val second : String = first) {
def this(f : String, s : String) = this(f)(s)
}
...потому что Карри-версия переводится (среди прочего) в метод с той же сигнатурой, что и перегруженный контруктор.
из 5.3 спец:
область действия параметра formal value включает все последующие разделы параметров и шаблон t.
обычные методы одинаковы, кстати (из 4.6):
объем формальному параметру имя x включает в себя все последующие предложения параметров, а также тип возвращаемого метода и тело функции, если они с учетом.
т. е., если у вас есть конструктор или обычный метод, имя параметра value не находится в области действия в собственном предложении parameter. В вашей второй версии конструктор имеет два предложения параметров и first
находится только в области во втором. См. 5.3 более подробно о нескольких пунктах параметра.