I'm trying to understand the behavior of Scala for-loop implicit box/unboxing of "numerical" types. Why does the two first fail but not the rest?

1) Fails:

scala> for (i:Long <- 0 to 10000000L) {}

      <console>:19: error: type mismatch;<br>
      found   : Long(10000000L)
      required: Int
              for (i:Long <- 0 to 10000000L) {}
                                  ^

2> Fails:

scala> for (i <- 0 to 10000000L) {}

      <console>:19: error: type mismatch;
      found   : Long(10000000L)
      required: Int
          for (i <- 0 to 10000000L) {}
                         ^

3) Works:

scala> for (i:Long <- 0L to 10000000L) {}

4) Works:

scala> for (i <- 0L to 10000000L) {}

有帮助吗?

解决方案

It has nothing to do with the for-loop:

0 to 1L   //error
0 to 1    //fine
0L to 1L  //fine
0L to 1   //fine

It's just because the to method available to Int expects an Int as its argument. So when you give it a Long it doesn't like it, and you get an error.

Here's the definition of the to method, found on RichInt:

def to(end: Int): Range.Inclusive = Range.inclusive(self, end)

其他提示

The desugaring and implicit transformation of numerical types is inconsistent i.e differ between the "for/comprehension" expressions compared to assignment operations. Please feel free to prove otherwise or at least point where the argument below is flawed:

In fact, during numeric assignment the Destination type is dominant.

var l:Long = 0 becomes:
val l: Long = 0L

var l:Long = 0.toInt becomes:
var l: Long = 0.toInt.toLong

During "for/comprehension" expressions the Source type is dominant:

for (i:Long <- 0 to 1000000000L) { } becomes:
0.to(1000000000L).foreach(((i: Long) => ()))

for (i <- 0L to 1000000000L) { } becomes: scala.this.Predef.longWrapper(0L).to(1000000000L).foreach[Unit](((i: Long) => ()))

(ps: output generated with the "-Xprint:typer -e" compiler flag. ds)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top