Не могу ли я определить значения по умолчанию, если я определяю несколько перегруженных конструкторов в Scala?

Я определил несколько конструкторов с некоторыми значениями аргументов по умолчанию во всех них. Выглядит правильно (я не вижу никакой двусмысленности), но компилятор Scala (2.8) жалуется:

несколько перегруженных альтернатив конструктора определяют аргументы по умолчанию

Означает ли это, что я вообще не могу определить значения по умолчанию для перегруженных конструкторов?

Позвольте мне проиллюстрировать ситуацию (примитивизированную, конечно, но иллюстративную):


class A(subject : Double, factor : Int = 1, doItRight : Boolean = true) {

  def this (subject : Int, factor : Int = 1, doItRight : Boolean = true) = {
    this(subject.toDouble , factor, doItRight)
  }

  def this (subject : String, factor : Int = 1, doItRight : Boolean = true) = {
    this(subject.toDouble , factor, doItRight)
  }

  def this () = {
    this(defaultSubject)
  }

}



Ответы

Ответ 1

Взято прямо из исходного кода компилятора:

// only one overloaded alternative is allowed to define default arguments

В общем, я бы не советовал вам смешивать перегрузки и значения по умолчанию. Даже если нет конфликта, это может сделать ваш код более трудным для чтения.

ОБНОВЛЕНИЕ

Поскольку вы добавили код, теперь ясно, что вам не нужно/нужно переопределять значения по умолчанию для каждого вторичного конструктора. В вашем конкретном случае я мог бы даже расспросить о необходимости этих дополнительных конструкторов; Int = > Double уже доступен для вас как неявное преобразование, а String = > Double выглядит так, как будто вы извращаете систему типов:)

Также... В качестве альтернативы перегруженным конструкторам вы можете определить только первичный конструктор со значениями по умолчанию, а затем перегрузить метод apply сопутствующего объекта и использовать его как factory. Это, конечно, совершенно необязательно, но оно быстро устанавливается как шаблон с использованием классов case.

Ответ 2

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

class A(subject : Double, factor : Int = 1, doItRight : Boolean = true) {

  def this (subject : Int) = {
    this(subject.toDouble)
  }

  def this (subject : String) = {
    this(subject.toDouble)
  }

  def this () = {
    this(defaultSubject)
  }
}