I would to make the second constructor argument optional, and use the value of the first argument in that case. Is there any way I can do that ? This code doesn't compile as it can't find realUser
:
class CurrentUser(val realUser:String, val masqueradeUser:String = realUser)
I'm sure I can work around it by writing my own constructor, but I wondered if there were a more concise way. Actually now that I've tried writing my own constructor, it isn't that bad:
class CurrentUser(val realUser:String, val masqueradeUser:String) {
def this(realUser:String) = this(realUser, realUser)
}
If someone can come up with something shorter then great, otherwise I'll post my own answer.
Supplying default constructor parameters has at least two benefits: You provide preferred, default values for your parameters. You let consumers of your class override those values for their own needs.
You can assign a default value for a parameter using an equal to symbol. I gave a default value for the first parameter. If the caller doesn't pass any value for the first parameter, Scala will take the default value as println. That's it.
Scala provides the ability to give parameters default values that can be used to allow a caller to omit those parameters. The parameter level has a default value so it is optional. On the last line, the argument "WARNING" overrides the default argument "INFO" .
A parameter with a default value, is often known as an "optional parameter". From the example above, country is an optional parameter and "Norway" is the default value.
I believe your solution with the auxiliary constructor is the better one. A parameter is not visible in its own parameter list, only in the following ones. So you would have to do
class CurrentUser(val realUser: String)(val masqueradeUser: String = realUser)
and then call with
new CurrentUser(real)()
Not too nice.
You can’t reuse parameters from the same parameter list as default arguments. didierd’s solution works, and probably your solution with a second constructor is the most elegant. Here's a third alternative, which uses the dreaded null
:
scala> class CurrentUser(val realUser:String, _masqueradeUser: String = null) {
| val masqueradeUser = if (_masqueradeUser == null) realUser else _masqueradeUser
| }
defined class CurrentUser
scala> new CurrentUser("paul").masqueradeUser
res1: String = paul
scala> new CurrentUser("paul", "p").masqueradeUser
res2: String = p
If you want to avoid null
, you can use the Opt[A]
class discussed here if you don't mind the overhead. One way or another, I’d still go with your second-constructor solution.
Thanks for the suggestions. I think I will stick with specifying the second constructor form manually. Here it is as an answer for completeness' sake.
class CurrentUser(val realUser:String, val masqueradeUser:String) {
def this(realUser:String) = this(realUser, realUser)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With