[英]Scala alternative to an infinite loop
Is there any more functional alternative in Scala for an infinite loop?在 Scala 中是否有更多功能替代品用于无限循环?
while(true) {
if (condition) {
// Do something
} else {
Thread.sleep(interval);
}
}
You can do it recursively你可以递归地做
@tailrec
def loop(): Nothing = {
if (condition) {
// Do something
} else {
Thread.sleep(interval);
}
loop()
}
One thing that you can do is using higher-order functions like Stream.continually
and pair it up with a for
comprehension:您可以做的一件事是使用像
Stream.continually
这样的高阶函数,并将其与 a 配对以for
理解:
import scala.util.Random
import scala.collection.immutable.Stream.continually
def rollTheDice: Int = Random.nextInt(6) + 1
for (n <- continually(rollTheDice)) {
println(s"the dice rolled $n")
}
This example itself is not purely functional due to the non-referentially transparent nextInt
method, but it's a possible construct that may help you think about function composition rather then using side effects.由于非引用透明的
nextInt
方法,此示例本身并不是纯函数式的,但它是一种可能的构造,可以帮助您考虑函数组合而不是使用副作用。
As correctly point out in a recent comment, "[a]s of 2.13, Stream is deprecated. But the same method does exist in LazyList(import scala.collection.immutable.LazyList.continually)".正如在最近的评论中正确指出的那样,“[a] s of 2.13,Stream 已弃用。但 LazyList(import scala.collection.immutable.LazyList.continually) 中确实存在相同的方法”。
The following will work from 2.13 onward:从 2.13 开始,以下内容将起作用:
import scala.util.Random
import scala.collection.immutable.LazyList.continually
def rollTheDice: Int = Random.nextInt(6) + 1
for (n <- continually(rollTheDice)) {
println(s"the dice rolled $n")
}
You can see it in action and play around with it here on Scastie .您可以在 Scastie 上看到它的实际运行情况并进行操作。
I guess infinite tail recursion:我猜无限尾递归:
@tailrec
def loop(): Nothing = {
if (condition) {
// Do something
} else {
Thread.sleep(interval);
}
loop()
}
Just to add to Stefano's great answer, in case someone is looking to a use-case like mine:只是为了补充 Stefano 的好答案,以防有人正在寻找像我这样的用例:
I was working on tasks from Kafka Streams course and needed to create an infinite stream of mock events to Kafka with some fields being completely random(amounts), but others rotated within a specific list(names).我正在处理 Kafka Streams 课程中的任务,需要为 Kafka 创建无限的模拟事件流,其中一些字段是完全随机的(数量),但其他字段在特定列表(名称)中轮换。
The same approach with continually
can be used passing a method(via ETA expansion) to it and traversing the bounded variable afterwards:可以使用与
continually
相同的方法将方法(通过 ETA 扩展)传递给它,然后遍历有界变量:
for {record <- continually(newRandomTransaction _)
name <- List("John", "Stephane", "Alice")} {
producer.send(record(name))
}
where the signature of newRandomTransaction
is as follows:其中
newRandomTransaction
的签名如下:
def newRandomTransaction(name: String): ProducerRecord[String, String] = {
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.