我有一个关于 this 的问题文章。
这段代码之间
function odds(n, p) {
if(n == 0) {
return 1
} else {
return (n / p) * odds(n - 1, p - 1)
}
}
和这段代码
(function(){
var odds1 = function(n, p, acc) {
if(n == 0) {
return acc
} else {
return odds1(n - 1, p - 1, (n / p) * acc)
}
}
odds = function(n, p) {
return odds1(n, p, 1)
}
})()
1) 我对这有多大帮助感到困惑。第二个片段是否只是有一个尾部调用,因为它在再次调用自己之前计算了它需要的东西,所以产生了更少的开销,还是我遗漏了更多东西?
据我了解,尾调用仍然没有被消除,只是被优化了。
2) 为什么还需要 odds
和 odds1
?我也不清楚。
最佳答案
I'm confused about how much this helps. Does the second snippet simply have a tail call that creates less overhead because it calculates what it needs before it calls itself again, or is there something more I'm missing?
As I understand it, the tail call still isn't eliminated, just optimized.
如果程序的结尾是这样的:
push args
call foo
return
然后编译器可以将其优化为
jump startOfFoo
完全消除过程调用。
And why does there need to be odds and odds1 anyway? It still isn't clear to me either.
odds
的“契约(Contract)”仅指定两个参数 - 第三个参数只是一个实现细节。因此,您将其隐藏在一个内部方法中,并提供一个“包装器”作为外部 API。
我认为,您可以将 odds1
称为 oddsImpl
之类的名称,这样会更清晰。
关于javascript - 关于 "Tail Call Optimization"文章的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4707888/