For循环scala没有序列?
因此,当我通过“Scala for the Impatient”工作时,我发现自己想知道:如果没有序列,您可以使用Scala for循环吗?For循环scala没有序列?
例如,本书中有一项练习要求您构建一个无法在Integer.MAX_VALUE之前递增的计数器对象。为了测试我的解决方案,我写了下面的代码:
var c = new Counter
for(i <- 0 to Integer.MAX_VALUE) c.increment()
这将引发一个错误:序列不能包含Int.MaxValue元素更多。 在我看来,这意味着Scala首先分配并填充序列对象,值为0到Integer.MaxValue,然后对该序列对象执行foreach循环。
我知道我能做到这一点,而不是:
var c = new Counter
while(c.value < Integer.MAX_VALUE) c.increment()
但有没有办法做一个传统的C风格的for循环与for语句?
事实上,0 to N
实际上不填充整数从东西向0
N
。它会创建一个scala.collection.immutable.Range
的实例,该实例将其方法应用于动态生成的所有整数。
您遇到的错误仅仅是因为您必须能够将Int
的正数部分(无论它们实际存在与否)纳入其正数部分,以便维护length
方法的合同。 1 to Int.MaxValue
正常工作,因为0 until Int.MaxValue
。而后者就是你的while循环所做的(to
包含正确的端点,until
省略了它)。
无论如何,因为斯卡拉for
是一个非常不同的(更通用)的生物比C for
,简单的答案是否定的,你不能做同样的事情。但是你可以用for
做你想做的事(尽管可能不如你想的那么快,因为有一些性能损失)。
是和否,这取决于您要求的内容。如果你问你是否可以通过整数序列重复,而不必首先建立一个序列,然后是你可以,例如使用流:
def fromTo(from : Int, to : Int) : Stream[Int] =
if(from > to) {
Stream.empty
} else {
// println("one more.") // uncomment to see when it is called
Stream.cons(from, fromTo(from + 1, to))
}
然后:
for(i <- fromTo(0, 5)) println(i)
编写您自定义hasNext和next是另一种选择。
如果你问是否可以使用'for'语法来编写一个“本地”循环,即循环通过增加一些本地整数来工作,而不是迭代对象实例产生的值,那么就我所知,答案是不。正如你可能知道的,'for'理解是句法糖,用于调用flatMap,filter,map和/或foreach(全部在FilterMonadic特性中定义)的组合,具体取决于生成器及其类型的嵌套。您可以尝试编译一些循环并打印其编译器中间表示形式,其中包含
scalac -Xprint:refchecks
以查看它们是如何扩展的。
这里有一堆这些,但我不能困扰他们目前搜索。以下是相当典型:
@scala.annotation.tailrec
def loop(from: Int, until: Int)(f: Int => Unit): Unit = {
if (from < until) {
f(from)
loop(from + 1, until)(f)
}
}
loop(0, 10) { i =>
println("Hi " + i)
}
哇,一个简单的问题,一些不错的技术解答(这是很好的!),但如果有些人只是为了寻找一个简单的答案:
//start from 0, stop at 9 inclusive
for (i <- 0 until 10){
println("Hi " + i)
}
//or start from 0, stop at 9 inclusive
for (i <- 0 to 9){
println("Hi " + i)
}
獭指出,“到”包括右端点“,直到”省略“。
哇,一个具有挑战性的答案,但一个很好的答案。我只是在学习Scala,所以你用了很多我只是不太熟悉的术语,但是谢谢。 –
'fromTo'的定义可以通过在'Stream'(或'Iterator')伴随对象上使用'iterate'方法进一步简化。 (def fromTo(from:Int,to:Int)= Stream.iterate(from,to - from)(_ + 1)')。但是使用'from to to'更加习惯并且达到同样的效果。 –