左图:一般递归 右图: 弹床尾随递归(为啥叫弹床,后面会详细介绍)
虽然两种尾随递归看起来没什么不同, 但是在递归一层层深入时就会发生意想不到的错误,先看看两种实现
第一种: 一般递归, 相信各位也经常使用的
当数值100000或者更多时,递归的层次就越深(参考图一), 但是报错的原因是什么呢?
这是因为每次对于sum的递归调用,都会由系统的一种 栈帧 的东西管理和分配,调用过程中会导致递归的实现很慢而且有可能很快就耗尽了栈空间(也就是栈溢出).
可以见得平时递归的方法使用既危险也不优雅.
第二种:为了避免内存溢出和重复的创建分配内存,当然使用图一右的弹床尾随递归.先上图
这里不同的地方就是在return后跟随的是一个 func尾递归函数的返回值, 这样就变成简单的函数递归调用, 没有任何额外的运算。
//注释:为什么叫做弹床呢?是因为弹床机制本质上就是把递归调用转化为循环调用。递归会先连续的压栈(递归调用),返回的时候再连续地出栈。而弹床的话,每次执行调用压栈一次(函数调用),然后马上出栈(函数返回)。循环往复这个过程。如果把栈比作蹦床的话,这个过程就像在跳蹦床一样。落下就是压栈,弹起就是出栈。交替进行。
!!!注意,注意,注意的地方(重要的事情将三遍):如果你在项目中直接尝试运行这段代码的话还是会报错,因为Debug模式下Swift编译器并不会对尾递归进行优化.我们可以在 选择Product->Scheme->Edit Scheme中设置中将Run配置从Debug改为Release
仍有不清楚的童鞋可以留言给我哈
选择Product->Scheme->Edit Scheme