user477768
user477768

Reputation:

Why does val range = Range(1, 2, 3, 4) give error?

for (i <- Array.apply(1 to 4))
      print(i);

Range(1, 2, 3, 4)

Range(1, 10)

//res0: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)

So why does val range = Range(1, 2, 3, 4) give error?

Upvotes: 2

Views: 813

Answers (2)

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297195

Well,

scala> Array("abc") // an array containing a string
res0: Array[String] = Array(abc)

scala> Array(1) // an array containing a number
res1: Array[Int] = Array(1)

scala> Array(true) // an array containing a boolean
res2: Array[Boolean] = Array(true)

scala> Array(1 to 4) // an array containing a range
res3: Array[scala.collection.immutable.Range.Inclusive] = Array(Range(1, 2, 3, 4))

Why should it have worked any other way? Anyway, this is what you should have used:

scala> Array.range(1, 4)
res4: Array[Int] = Array(1, 2, 3)

Upvotes: 0

dhg
dhg

Reputation: 52681

A Range is a special kind of collection that is restricted in what it can represent in order to efficiently perform its operations. It is only able to represent a sequence of numbers with a fixed step in between elements. As such, it only needs to be told about the start, end, and step size in order to be constructed. An Array on the other can hold arbitrary values, so its constructor must be told explicitly what those values are.

The definition of Range.apply is that it takes either:

  • two arguments: a start and end for a range, or
  • three arguments: a start, end, and step size for the range.

Here are the definitions of apply from scala.collection.immutable.Range:

/** Make a range from `start` until `end` (exclusive) with given step value.
 * @note step != 0
 */
def apply(start: Int, end: Int, step: Int): Range = new Range(start, end, step)

/** Make an range from `start` to `end` inclusive with step value 1.
 */
def apply(start: Int, end: Int): Range = new Range(start, end, 1) 

Constrast this with the apply for scala.Array, which accepts a variable-length argument T*:

/** Creates an array with given elements.
 *
 *  @param xs the elements to put in the array
 *  @return an array containing all elements from xs.
 */
def apply[T: ClassManifest](xs: T*): Array[T] = {
  val array = new Array[T](xs.length)
  var i = 0
  for (x <- xs.iterator) { array(i) = x; i += 1 }
  array
}

If your goal is to have an Array of the numbers 1 to 4, try this:

(1 to 4).toArray

Upvotes: 11

Related Questions