2
class testing[T <: IntStorage : ClassTag] {
  var the_array = Array.ofDim[T](10, 10)
}

I wonder what "the_array" contains before putting any element in it if T is an abstract class? So what are the initial elements of the array?

And what if the array can also contain empty elements, None for example. How could I first initialize the array with all "empty", i.e. None, cells and then fill certain rows and columns?

1
  • 2
    None is not "empty". It is a stand-alone object and part of Option[X]. Commented Dec 28, 2021 at 3:10

1 Answer 1

4

Scala, for all of the things it does right, unfortunately still harbors the worst criminal from the Java realm: the dreaded null value, often called the billion dollar mistake.

In Scala, every AnyRef value (roughly speaking, anything that would be non-primitive in Java) can be null. It's not idiomatic to do this, and any seasoned Scala dev will avoid null like the plague. But it's there, like a specter, waiting to leap up and bite unsuspecting programmers in the night.

Array.ofDim returns default-initialized values. For AnyVal, this means their "zero" value, so Array.ofDim[Int] returns an array of zeroes. For AnyRef, this returns an array of null.

scala> var x = Array.ofDim[A](10) // Assuming A is some class
var x: Array[A] = Array(null, null, null, null, null, null, null, null, null, null)

Ideally, you'll want to fill the array with something sensible immediately. Or, even better, use the Array.fill method, which works the exact same way but allows you to immediately initialize the array values.

Note that Scala 3 has an opt-in compiler option called -Yexplicit-nulls, which explicitly marks any value that can potentially be null and makes it explicit in the type system. Unfortunately, it seems that Array.ofDim still returns an Array[T] even in this mode, effectively making its type a lie in Scala 3's new null checker. I conclude that ofDim is likely intended as a "low-level" primitive for allocating empty arrays, and that fill should probably be used instead in most cases, in the same way that asInstanceOf is a low-level primitive which should be avoided in favor of pattern matching (or simply avoiding downcasting altogether, ideally).

Sign up to request clarification or add additional context in comments.

2 Comments

I would also point out that tabulate is also very useful. - On top of that, it is worth pointing that Array is also another carry over from Java and proper collections should be preferred.
Just a nitpick: "every AnyRef value can be null" is mostly true, but not exactly, which is why you need to write things like Ident >: Null <: AnyRef when you want to handle nullable values in your generics (see stackoverflow.com/questions/18054614/…)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.