The fill
method is defined with it's second parameter as "call-by-name". This means that the passed-in block is re-evaluated for every cell in the Array. See in the definition that the type of elem
is => T
, not simply T
:
def fill[T: ClassManifest](n: Int)(elem: => T): Array[T]
So in your first version, the block new A
is re-evaluated for each cell, meaning that each cell gets a fresh A
object. In the second version, new A
is called only once, and that object is placed into every cell.
You can actually see this if you run on the REPL:
scala> val b = Array.fill(2)(new A)
b: Array[A] = Array(A@2049bed2, A@498edd8d) // two different objects
scala> val c = Array.fill(2)(a)
c: Array[A] = Array(A@31e0c0b6, A@31e0c0b6) // the same object repeated