为什么Scala for-loop(和内部)NumericRange限制为Int大小以及如何详细说明功能?

IOD*_*DEV 10 for-loop scala restriction

对Scala for-loop理解的NumericRange Int大小限制背后的原因是什么?是否有可能(没有太多头痛)扩展"for/Seqs"NumericRange以使用Long(或任何大于Int.MaxValue的东西)?

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

java.lang.IllegalArgumentException: 0 to 10000000000L by 1: "seqs cannot contain more than Int.MaxValue elements."
    at scala.collection.immutable.NumericRange$.count(NumericRange.scala:227)
    at scala.collection.immutable.NumericRange.numRangeElements(NumericRange.scala:53)
    at scala.collection.immutable.NumericRange.length(NumericRange.scala:55)
    at scala.collection.immutable.NumericRange.foreach(NumericRange.scala:73)
    at .<init>(<console>:19)
    at .<clinit>(<console>)
    at .<init>(<console>:11)
    at .<clinit>(<console>)
    at $print(<console>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
    at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
    at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
    at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
    at java.lang.Thread.run(Thread.java:680)
Run Code Online (Sandbox Code Playgroud)

-
提前谢谢!

dre*_*xin 9

在Scala中没有for循环,而是for-comprehension.它的工作方式与循环不同.实际上你的理解被翻译成:

(0L to 10000000000).map { i => // (0L to 10000000000) == collection.immutable.NumericRange.inclusive(0L, 10000000000,1)
  // block
}
Run Code Online (Sandbox Code Playgroud)

限制不在for-comprehension中,而是在Seq类型中,它不能包含多个Int.MaxValue元素.如果你真的需要10000000000x循环,你仍然可以使用

var i = 0L
while(i < 10000000000) {
  // do stuff
  i+=1
}
Run Code Online (Sandbox Code Playgroud)

  • @Nicolas你是对的,Monad不是Scala中的一个类型,但是`for(...)yield`需要实现`map`和`flatMap`的任何东西,一个简单的`for`没有`yield`会占用任何东西,这已经实现了.您可能想阅读Scala中Monads上的这篇文章:http://james-iry.blogspot.de/2007/09/monads-are-elephants-part-1.html (2认同)

Ed *_*aub 8

简短回答 - 它似乎是一个"功能" - 至少,它是按设计工作的.

正如@drexin指出的那样,"to"的实现仅限于具有Int范围.然而...

问题是NumericRange [T] .count(),. numRangeElements和.length()返回一个Int - 无论T是什么.在这种情况下,它是一个NumericRange [Long],将count()限制为31位似乎有点不对,恕我直言.
然而...

从浏览Jira问题来看,这似乎是按设计工作的.参见,例如,SI-4370.但是为了确保从这个角度考虑过,我进入了SI-5619.

  • 这绝对是一个缺陷.因为您可以构建这样的Range,但是一旦调用需要检查其长度的方法它就会失败. (3认同)