为什么Scala for循环(和内部)numeriRange限制为Int size,以及如何详细说明功能?

为什么Scala for循环(和内部)numeriRange限制为Int size,以及如何详细说明功能?,scala,for-loop,restriction,Scala,For Loop,Restriction,Scala for循环理解的NumericRange Int size限制背后是什么?是否有可能(不太麻烦)扩展“for/Seqs”numeriRange以使用Long(或大于Int.MaxValue的任何内容) scala>for(i:Long在scala中,没有for循环,而是for consummation。它的工作原理与循环不同。实际上,for consummation被转换为: (0L to 10000000000).map { i => // (0L to 1000000000

Scala for循环理解的NumericRange Int size限制背后是什么?是否有可能(不太麻烦)扩展“for/Seqs”numeriRange以使用Long(或大于Int.MaxValue的任何内容)


scala>
for(i:Long在scala中,没有for循环,而是for consummation。它的工作原理与循环不同。实际上,for consummation被转换为:

(0L to 10000000000).map { i => // (0L to 10000000000) == collection.immutable.NumericRange.inclusive(0L, 10000000000,1)
  // block
}
To限制不在理解中,而是在Seq类型中,它不能包含超过Int.MaxValue的元素。如果您确实需要1000000000x循环,您仍然可以使用

var i = 0L
while(i < 10000000000) {
  // do stuff
  i+=1
}
var i=0L
而(i<1000000000){
//做事
i+=1
}

简短回答-这似乎是一个“功能”-至少,它按设计工作

正如@drexin所指出的,“to”的实现仅限于Int范围

问题是NumericRange[T].count()、.numRangeElements和.length()返回一个Int,而不管T是什么。在这种情况下,它是一个NumericRange[Long],将count()限制为31位似乎有点错误,IMHO。
然而


通过浏览Jira问题,这似乎是按设计工作的。例如,请参见。但为了确保从这个角度考虑到了这一点,我输入了。

方法
size
length
返回
Int
,因此它们不可能返回大于
Int.MaxValue
的值
Seq
,同样,
apply
方法采用
Int
,存在同样的问题。因此,Scala集合与Java集合一样,仅限于
Int.MaxValue
元素。

只要它们的计数不符合
Int
的要求,就不能对元素进行计数,因为
length
是declared返回
Int
,但这里有一个快捷方式:您可以创建任何实际大小的迭代器,只要您不尝试计数它们

scala> def longRange(first: Long, last: Long) = new Iterator[Long] {
    private var i = first
    def hasNext = i < last
    def next = {val r = i; i += 1; r}
}
longRange: (from: Long, to: Long)java.lang.Object with Iterator[Long]

scala> val lol = longRange(0, Long.MaxValue) map (x => x * x)
lol: Iterator[Long] = non-empty iterator

scala> lol drop 5 take 5 foreach println
25
36
49
64
81
scala>def longRange(first:Long,last:Long)=新迭代器[Long]{
私有变量i=第一
def hasNext=ivallol=longRange(0,Long.MaxValue)映射(x=>x*x)
lol:Iterator[Long]=非空迭代器
scala>lol每打印5次,每次打印5次
25
36
49
64
81

感谢您的重播,我非常了解sugar的理解语法。但重点是“为什么”Seq受到限制(如问题中所述)如果Seq很容易扩展?那么你的基本意思是for/comprehension不够成熟,无法在生产中使用?这是一个库设计缺陷还是一个语言问题?不,这只意味着
for
构造需要一系列元素,并且由于内存限制(请参阅我的答案的最新版本)。不,对于应用程序的非性能关键部分来说,理解是很好的。它比循环慢,但也更强大。如果您使用Monad来理解rock,而不是迭代大型集合。@Nicolas您是对的,Monad不是Scala中的类型,而是(…)的
yield
接受任何已实现的
map
flatMap
的内容,没有
for
简单的
yield
接受任何已实现foreach的内容。您可能想阅读这篇关于Scala中monad的文章:它不局限于一个范围,这正是您所创建的。您可以将任何monad传递给sion@Ed Staub-这正是我的观点,即为什么范围计数()被限制为Int!这很奇怪,但大问题仍然存在:这是一个bug还是一个特性;-)@drexin:知道范围计数为什么默认为Int吗?这肯定是一个缺陷。因为你可以建立这样一个范围,但是只要你调用一个需要检查其长度的方法,它就会失败。@Nicolas,这就是重点。如果未延迟计算
count
,则将引发异常,但对于
0L到1000000000l乘以1000000的情况,这是错误的。虽然
length
的行为可能有所不同(对于无限的集合也是如此),但
apply
不能。但是,可以肯定的是,理论上可以用无限的
流超过
Int.MaxValue
元素,因此这里肯定存在一些矛盾。因此,为了处理大于Int.MaxSize的Seq集合,我们需要一个BigSeq?;-)@IODEV这么大的收藏有一个实用的问题。我认为真正的问题可能是,范围不应该是集合,而应该转换成集合。Scala 2.9运行良好,Scala 2.10发出以下命令:Scala>def longRange(from:Long,to:Long)=新迭代器[Long]{私有变量I:Long=from | def hasNext=Ito
word搞糊涂了,因为有一个方法使用了这样的名称。也许他们的语法定义出了问题。顺便说一句,我开始认为Scala语法的这一部分(允许使用“空格样式”方法调用而不是“点样式”)对于所有名称,不仅像
++
++
,等等)这样的“特殊符号”是邪恶的。下面是一个工作示例:,如果我们将
end
重命名为
,它不会编译:。可能报告错误是合法的。
scala> def longRange(first: Long, last: Long) = new Iterator[Long] {
    private var i = first
    def hasNext = i < last
    def next = {val r = i; i += 1; r}
}
longRange: (from: Long, to: Long)java.lang.Object with Iterator[Long]

scala> val lol = longRange(0, Long.MaxValue) map (x => x * x)
lol: Iterator[Long] = non-empty iterator

scala> lol drop 5 take 5 foreach println
25
36
49
64
81