Как должны Scala аргументы по умолчанию ссылаться на предыдущий аргумент позиции? - программирование
Подтвердить что ты не робот

Как должны 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, это правильно? Является ли эта форма необходимой или есть какой-то синтаксический сахар, который я могу использовать, чтобы настроить первый конструктор на то, что я хочу?

4b9b3361

Ответ 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 для более подробной информации о нескольких параметрах.