amb*_*b85 1 tail-recursion kotlin
send()以下示例中的函数以递归方式调用自身:
internal inner class RouteSender(
val features: List<Feature>,
val exchange: GrpcUniExchange<Point, RouteSummary>
) {
var result: AsyncResult<RouteSummary>? = null // Set in stub for recordRoute.
fun send(numPoints: Int) {
result?.let {
// RPC completed or err'd before sending completed.
// Sending further requests won't error, but they will be thrown away.
return
}
val index = random.nextInt(features.size)
val point = features[index].location
println("Visiting point ${RouteGuideUtil.getLatitude(point)}, " +
"${RouteGuideUtil.getLongitude(point)}")
exchange.write(point)
if (numPoints > 0) {
vertx.setTimer(random.nextInt(1000) + 500L) { _ ->
send(numPoints - 1)
}
} else {
exchange.end()
}
}
}
Run Code Online (Sandbox Code Playgroud)
它可以重写,以便执行的最后一个操作是对自身的递归调用:
...
if (numPoints <= 0) {
exchange.end()
} else {
vertx.setTimer(random.nextInt(1000) + 500L) { _ ->
send(numPoints - 1)
}
}
...
Run Code Online (Sandbox Code Playgroud)
然而,如果我将它标记为一个tailrec函数,我会收到一个警告:递归调用不是尾调用.这不会停止编译程序的成功运行.但是,为什么这不是尾巴召唤?
该文件说:
要获得
tailrec修饰符的资格,函数必须将自身称为它执行的最后一个操作.当递归调用后有更多代码时,您不能使用尾递归,并且您不能在try/catch/finally块中使用它.
这不在try/catch/finally块中,并且在递归调用之后没有更多代码.这是什么意味着这个代码块不适合尾递归优化?
我会回答我自己的问题,因为它没有回报价值.基于这个讨论,这就是我能想到的一切.思考?
尽管您的方法似乎包含对自身的调用,但实际上它根本不是递归方法.
调用send显示在闭包内.这意味着它不会立即被调用.只有在调用闭包本身时才会调用它.在你的情况下,这是由计时器完成的.它将发生在当前调用堆栈之外,甚至可能在当前线程之外.
在任何情况下,最后一次通话都是通话vertx.setTimer.
| 归档时间: |
|
| 查看次数: |
488 次 |
| 最近记录: |