How to provide default values for Scala constructor parameters

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.”

Back to top

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.

Back to top

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
Back to top

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"
}
Back to top

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
Back to top

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.

Back to top

See Also

Back to top

The Scala Cookbook

This tutorial is sponsored by the Scala Cookbook, which I wrote for O’Reilly:

You can find the Scala Cookbook at these locations:

Back to top

Add new comment

The content of this field is kept private and will not be shown publicly.

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.