Table of Contents
This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 4.5, “How to provide default values for Scala constructor parameters.”
Problem
You want to provide a default value for a Scala constructor parameter, which gives other classes the option of specifying that parameter when calling the constructor, or not.
Solution
Give the parameter a default value in the constructor declaration. Here’s a simple declaration of a Socket
class with one constructor parameter named timeout
that has a default value of 10000
:
class Socket (val timeout: Int = 10000)
Because the parameter is defined with a default value, you can call the constructor without specifying a timeout
value, in which case you get the default value:
scala> val s = new Socket s: Socket = Socket@7862af46 scala> s.timeout res0: Int = 10000
You can also specify the desired timeout
value when creating a new Socket
:
scala> val s = new Socket(5000) s: Socket = Socket@6df5205c scala> s.timeout res1: Int = 5000
If you prefer the approach of using named parameters when calling a constructor (or method), you can also use this approach to construct a new Socket
:
scala> val s = new Socket(timeout=5000) s: Socket = Socket@52aaf3d2 scala> s.timeout res0: Int = 5000
Discussion
This recipe demonstrates a powerful feature that can eliminate the need for auxiliary constructors. As shown in the Solution, the following single constructor is the equivalent of two constructors:
class Socket (val timeout: Int = 10000)
If this feature didn’t exist, two constructors would be required to get the same functionality; a primary one-arg constructor and an auxiliary zero-args constructor:
class Socket(val timeout: Int) { def this() = this(10000) override def toString = s"timeout: $timeout" }
Multiple parameters
Taking this approach a step further, you can provide default values for multiple constructor parameters:
class Socket(val timeout: Int = 1000, val linger: Int = 2000) { override def toString = s"timeout: $timeout, linger: $linger" }
Though you’ve defined only one constructor, your class now appears to have three constructors:
scala> println(new Socket) timeout: 1000, linger: 2000 scala> println(new Socket(3000)) timeout: 3000, linger: 2000 scala> println(new Socket(3000, 4000)) timeout: 3000, linger: 4000
Using named parameters
As shown in the Solution, you can also provide the names of constructor parameters when creating objects, in a manner similar to Objective-C and other languages. This means you can also create new Socket
instances like this:
println(new Socket(timeout=3000, linger=4000)) println(new Socket(linger=4000, timeout=3000)) println(new Socket(timeout=3000)) println(new Socket(linger=4000))
See Recipe 5.4, “Using Parameter Names When Calling a Scala Method”, for more examples of how to use parameter names in method calls.
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |
See Also
- Recipe 4.3, “Defining Auxiliary Constructors in Scala” for more information on creating auxiliary class constructors