kotlin - 满足提供的条件时如何从传递给递归函数的 lambda 中断
问题描述
我正在编写一个自定义loop
dsl,我希望它的用法如下所示
var counter1 = 0
var counter2 = 0
loop {
counter1 += 1
println(counter1)
stopIf(counter1 == 5) // loop should terminate here and not execute rest of the code if condition matches
counter2 += 2
println(counter2)
stopIf(counter2 == 8) // loop should terminate here and not execute rest of the code if condition matches
}
我有以下代码,它允许我stopIf
在主体中的任何地方编写任意次数,loop
但是当条件匹配时,它不会立即终止,而是执行循环体的其余部分,然后终止。
@UseExperimental(ExperimentalTime::class)
open class Loop {
var stop = false
val loopInterval = 1.seconds
suspend fun loop(block: suspend () -> Unit): Unit = loop(loopInterval, block)
suspend fun loop(minimumInterval: Duration, block: suspend () -> Unit): Unit =
loopWithoutDelay { delayedResult(maxOf(minimumInterval, loopInterval), block) }
private suspend fun loopWithoutDelay(block: suspend () -> Unit) {
block()
if (stop) return else loopWithoutDelay(block)
}
suspend fun <T> delayedResult(minDelay: Duration, f: suspend () -> T): T = coroutineScope {
val futureValue = async { f() }
delay(minDelay.toJavaDuration())
futureValue.await()
}
fun stopIf(condition: Boolean) {
if (condition) {
stop = condition // once stop condition matches, then do not override it with following false condtions
}
}
}
@ExperimentalTime
suspend fun loop(block: suspend Loop.() -> Unit) =
Loop().run { loop { block(this) } }
我曾尝试使用return
withlabel
但它不起作用。有什么办法可以做到这一点?
解决方案
例如,可以通过抛出轻量级异常来完成。您必须声明自定义异常:
class LoopStopException : Throwable("Stop look", null, false, false) // lightweight throwable without the stack trace
并抓住它loopWithoutDelay
:
private suspend fun loopWithoutDelay(block: suspend () -> Unit) {
try {
while (true) {
block()
}
} catch (e: LoopStopException) {
//do nothing
}
}
推荐阅读
- java - 如何使用java将普通英语、俄语(西里尔文)和编码俄语字符串的混合字符串转换为普通字符串
- android - 文本小部件中数字数据的颤动百分比
- json - 如何使用 ubuntu bash foreach json 数组名称值 az 组列表
- sql - 使用从列表框中传递的值访问 VBA 运行查询
- java - 使用输入的数字创建一个星方
- image - 如何使用 Flutter 将图像上传到服务器
- javascript - 将 cookie 数据从父级发送到 iframe
- ios - UIRefreshControl 正常运行但没有动画
- python - 将大型 Pandas Dataframe 从“稀疏”浮点数转换为 int
- android - 如何在 Firebase 中节省云空间