开发者

Can't I define defaults if I define multiple overloaded constructors in Scala?

开发者 https://www.devze.com 2023-01-19 21:35 出处:网络
I\'ve defined multiple constructors, with some default argument values in all of them. Looks correct (I can\'t see any ambiguity), but Scala (2.8) compiler complains:

I've defined multiple constructors, with some default argument values in all of them. Looks correct (I can't see any ambiguity), but Scala (2.8) compiler complains:

multiple overloaded alternatives of constructor define default arguments

Does it mean that I can't define default values for overloaded constructors at all?

Let me illustrate the situation (primitivized, of course, but illustrative):


class A(subject : Double, factor : Int = 开发者_StackOverflow中文版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)
  }

}




Taken straight from the compiler's source code:

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

In general, I wouldn't advise that you mix overloading and defaults. Even if there's no conflict it can make your code harder to read.

UPDATE

Since you added code, it's clear now that you don't want/need to override the default values for each secondary constructor. In your particular case, I might even question the need for those extra constructors at all; Int=>Double is already available for you as an implicit conversion and String=>Double looks like you might be perverting the type system :)

Also... As an alternative to overloaded constructors, you can define just the primary constructor with defaults, then overload the apply method of the companion object and use that as a factory. This is of course completely optional, but it's rapidly becoming established as a pattern through the use of case classes.


The overloading fails because you (unnessesarily) define multiple constructors with default values. Do this instead:

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


Yes, that's not convenient, you'll need to do without default arguments in your auxiliary constructors like:

class X(n: Int, verbose: Boolean = false) {

  def this(n: String, verbose: Boolean) = this(
      Integer.parseInt(n),
      verbose
  )

  def this(n: String) = this(n, false)
}

Mind though that inline (within a function) with default arguments different from each other you can do that:

def main(args: Array[String]): Unit = {

    class Y(n: Int, dummyImplicit: DummyImplicit = null, verbose: Boolean = false) {

        def this(n: String, verbose: Boolean = false) = this(
            Integer.parseInt(n), 
            verbose = verbose
        )
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消