17
scala> val a = Array [Double] (10)
a: Array[Double] = Array(10.0)

scala> val a = new Array [Double] (10)
a: Array[Double] = Array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)

Why these two expressions have different semantics?

4
  • Array managing in Scala is a pest.. only possible if you are developing on a frozen base Commented Apr 23, 2010 at 16:20
  • 3
    A "frozen base?" It's true array treatment changed considerably from 2.7 to 2.8, but I think we can expect it to remain stable hereafter. Now Scala Array is Java Array. Scala's "extra" array functionality is handled via implicits. Commented Apr 23, 2010 at 16:36
  • How do the implicts allow Array to get more functionality ? Commented Apr 23, 2010 at 16:48
  • 3
    You can write something like Array(1,2,3).map(_ * 0.5) and it will work exactly as if Array were a standard part of the Scala collections. But behind the scenes, it's implicitly placed into a wrapper class, and that wrapper is what calls map. So, on the one hand, Array[X] really is Java's X[], and on the other, you can pretend it's an almost-completely-integrated member of Scala's collections. Commented Apr 23, 2010 at 17:44

2 Answers 2

43

It's a bit confusing, but Scala has the notion of classes which you can create instances of, and objects, which are basically singleton instances of a class. It also has the notion of companion classes, which is a pair of a class and an object with the same name. This mechanism allows a "class" to essentially have static methods, which are otherwise not possible in Scala.

Array has both a class and a companion object. Furthermore, the Array object has an apply method. apply means you can create an object with Array(arg). But because Array is a companion class, it also has a constructor that can be called via the more usual mechanism of new Array(arg).

The issue is that apply in the the Array object has different semantics than the Array constructors. The apply method creates an array out of the specified objects, so, for example, Array(1,2,3) returns an array consisting of the objects 1, 2, and 3. The constructors, on the other hand, take arguments that specify the size of the dimensions of the array (so you can create multidimensional arrays), and then initialize all slots to a default value.

So, basically:

  • val a = Array [Double] (10) calls the apply method on the Array object, which creates a new array containing the given objects.
  • val a = new Array [Double] (10) calls the Array constructor, which creates a new array with 10 slots, all initialized to a default value of 0.0.
Sign up to request clarification or add additional context in comments.

2 Comments

@mipadi, how to create a new array with 10 slots and 1 as default value? Thanks
@city val a = Array.fill(10){1}
11

new Array[Double](10) is supposed to be equivalent to new double[10] in Java.

But Scala also provides convenience methods on the singletons corresponding to its collection classes, and Array is no exception.

Thus, if you can say List(1,2,3,4,5) it seems natural that you could also say Array(1,2,3,4,5). And you can.

But it does leave one in the slightly awkward position of having rather different results depending on whether one adds the word new or not. Given the competing interests, I think it's the best solution overall, but it does take a little getting used to.

Comments

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.