4.9. Setting Uninitialized var Field Types

Problem

You want to set the type for an uninitialized var field in a class, so you begin to write code like this:

var x =

and then wonder how to finish writing the expression.

Solution

In general, define the field as an Option. For certain types, such as String and numeric fields, you can specify default initial values.

For instance, imagine that you’re starting a social network, and to encourage people to sign up, you only ask for a username and password during the registration process. Therefore, you define username and password as fields in your class constructor:

case class Person(var username: String, var password: String) ...

However, later on, you’ll also want to get other information from users, including their age, first name, last name, and address. Declaring those first three var fields is simple:

var age = 0
var firstName = ""
var lastName = ""

But what do you do when you get to the address?

The solution is to define the address field as an Option, as shown here:

case class Person(var username: String, var password: String) {

  var age = 0
  var firstName = ""
  var lastName = ""
  var address = None: Option[Address]

}

case class Address(city: String, state: String, zip: String)

Later, when a user provides an address, you can assign it using a Some[Address], like this:

val p = Person("alvinalexander", "secret")
p.address = Some(Address("Talkeetna", "AK", "99676"))

When you need to access the address field, there are a variety of approaches you can use, and these are discussed in detail in Recipe 20.6. As one example, if you want to print the fields of an Address, calling foreach on the address field works well:

p.address.foreach { a =>
  println(a.city)
  println(a.state)
  println(a.zip)
}

If the field hasn’t been assigned, address is a None, and calling foreach on it does no harm, the loop is just skipped over. If the address field is assigned, it will be a Some[Address], so the foreach loop will be entered and the data printed.

Discussion

In a related situation, setting the type on numeric var fields can occasionally be interesting. For instance, it’s easy to create an Int or Double field:

var i = 0    // Int
var d = 0.0  // Double

In those cases, the compiler automatically defaults to the desired types, but what if you want a different numeric type? This approach lets you give each field the proper type, and a default value:

var b: Byte  = 0
var c: Char  = 0
var f: Float = 0
var l: Long  = 0
var s: Short = 0

See Also

  • The Option class

  • Don’t set fields like this to null; Scala provides a terrific opportunity for you to get away from ever using null values again. See Recipe 20.5, for ways to eliminate common uses of null values.

  • In many Scala frameworks, such as the Play Framework, fields like this are commonly declared as Option values. See Recipe 20.6, for a detailed discussion of this approach.

Get Scala Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.