Capacytron
Capacytron

Reputation: 3729

Scala case class, can't override constructor parameter

I have this case class:

 case class MyCaseClass(left:Long, right: Long = Option[Long], operator: Operator = Option[Operator]){

    def inRange(outer: Long) = outer >= left && outer <= right
  }

This is how I try to instantiate it:

val instance = MyCaseClass(leftValue)

But I get a compilation error:

Unspecified value parameters right, operator

What does this error mean? I just want to have two constructors for a case class: one with three params and one with one param.

This works (as Ende Neu suggested):

case class MyCaseClass(left:Long, right: Option[Long] = None, operator: Option[Operator] = None)

The problem is that I have to wrap right and operator in an Option. The below allows you to avoid Option wrapping for the right and operator parameters (see answer for more details):

object MyCaseClass {
  def apply(left: Long, right: Long, operator: Operator) = new MyCaseClass(left, Option(right), Option(operator))
}

Upvotes: 1

Views: 2396

Answers (1)

Ende Neu
Ende Neu

Reputation: 15773

You are not passing a default value, you are passing a type, if you want to pass default parameters you have to specify some value:

scala>  case class Operator(operation: String)
defined class Operator

scala>   case class MyCaseClass(left:Long, right: Long = 0L, operator: Operator = Operator("+")){
      |     def inRange(outer: Long) = outer >= left && outer <= right
      |   }
defined class MyCaseClass

scala>   val instance = MyCaseClass(10L)
instance: MyCaseClass = MyCaseClass(10,0,Operator(+))

If you want to wrap them in Option you have to declare them so:

 case class MyCaseClass(left:Long, right: Option[Long] = None, operator: Option[Operator] = None)

Where I used None as value, you could use also Some and pass some default value to them.

If you don't want the user to create a full object using options, create a companion object and define a new apply method:

case class Operator(operation: String)

object MyCaseClass {
  def apply(left: Long, right: Long, operator: Operator) = new MyCaseClass(left, Option(right), Option(operator))
}

case class MyCaseClass(left:Long, right: Option[Long] = None, operator: Option[Operator] = None)

You can now construct an object in different ways:

MycaseClass(10L)
MycaseClass(10L, Option(10L), Option(Operator("+"))
MycaseClass(10L, 20L, Operator("+"))

Upvotes: 4

Related Questions