nobody
nobody

Reputation: 2759

Scala initializing class level Array variable within a method


class Foo() {
 val array  // how do I leave initialization till later?
 def initializeArray(size : Int) = array = Array.ofDim[Int](size)
}

The above code won't compile, so how do I initialize my array at a later time?

Edit

Suppose I need to read a file that has a matrix of integer, and I want to represent the matrix as a two dimensional array. Of course, I am parsing the file inside the Foo class and the dimension of the matrix won't be known until the parsing is done.

Upvotes: 2

Views: 1388

Answers (2)

Emil L
Emil L

Reputation: 21081

You could use a lazy val e.g.

scala> class Foo {
     | lazy val array = initialize
     | def initialize = {
     | println("initializing...")
     | new Array[Int](5)
     | }
     | }
defined class Foo

scala> val f = new Foo
f: Foo = Foo@135810c

scala> f.array
initializing...
res46: Array[Int] = Array(0, 0, 0, 0, 0)

Now you have deferred when the array is initialized.

Upvotes: 4

dhg
dhg

Reputation: 52681

One simple way would be to just initialize it to null. To do this you would need to specify a type, Array[Int] and to make it a var (instead of val) so that you could change it later:

class Foo() {
  var array: Array[Int] = null  // how do I leave initialization till later?
  def initializeArray(size : Int) = array = Array.ofDim[Int](size)
}

However, this is not very good practice in Scala. It might be better to use an Option:

class Foo() {
  var array: Option[Array[Int]] = None  // how do I leave initialization till later?
  def initializeArray(size : Int) = array = Some(Array.ofDim[Int](size))
}

This tells a user, explicitly, that it is possible that array may not be set to anything, and avoids NullPointerExceptions. You can read more about Option on StackOverflow or elsewhere.

Finally, the best designs in Scala rely on immutable classes. In such a case, you would defer creation of the Foo until you actually know what you want to put in it. However, without knowing anything else about your design, it's hard to say how best to set this up.

EDIT: Based on your description, I would separate your design into two parts: a method for parsing the file, and an immutable Foo for storing the final result.

class Foo(array: Array[Int]) {

}

object Foo {
  def fromFile() = {
     val array: Array[Int] = /* parse file into the right structure */
     new Foo(array)
  }
}

Then you could just say:

val foo = Foo.fromFile(filename)

and the foo would be an complete, immutable Foo.

Upvotes: 3

Related Questions