How do I make a parameter the default value of another parameter in Scala?

Why can't I do the following:

def multiply(a: Int, b: Int = a) = a * b

or

case class Point(x: Int, y: Int = x)

Is there any other way to achieve the same? The reason I need this is because sometimes arguments that have different meanings are the exception rather than the rule. Take for example:

case class User(name: String, age: String, description: String, displayName: String = name, online: Boolean = false)

In 90% of cases, the display name and name should be the same, but in a few cases it should not have an edge. When using one parameter, the default value of the other will be very useful. Is there a way to do this? If not, why not?

+3


source to share


2 answers


Yes. Parameters in a parameter list can refer to the values ​​of arguments in previous parameter lists, in the same way as type inference can refer to types in previous parameter lists:

def multiply(a: Int)(b: Int = a) = a * b

case class Point(x: Int)(y: Int = x)

case class User(name: String, age: String, description: String)(displayName: String = name, online: Boolean = false)

      



must work.

+1


source


One way could be defining the case class as

case class User(name: String, age: String, description: String, displayName: String, online: Boolean = false) {
    def this(name: String, age: String, description: String, online: Boolean = true) =
    this(name, age, description, name, online)
}

      

Then you can create a case class like



  val user = new User("User name", "5", "description")
  //> user  : User = User(User name,5,description,User name,true)
  user.displayName
  //> res0: String = User name
  val userWithDisplayName = new User("User name", "5", "description", "displayName")
  //> userWithDisplayName  : User = User(User name,5,description,displayName,false)

      

You can also override the apply method in the companion object. This way you don't have to write a new one before creating the object.


scala> :paste
// Entering paste mode (ctrl-D to finish)
case class User(name: String, age: String, description: String, displayName: String, online: Boolean = false)
object User {
  def apply(name: String, age: String, description: String, online: Boolean) =
    new User(name, age, description, name, online)
}
// Exiting paste mode, now interpreting.
defined class User
defined module User
scala> User("User name", "5", "description", "displayName")
res0: User = User(User name,5,description,displayName,false)
scala> User("User name", "5", "description", true)
res1: User = User(User name,5,description,User name,true)
      

+1


source







All Articles