我尝试在Swift中执行以下简单函数:
func sum (n: Int, currentSum: Int = 0) -> Int { return n == 0 ? currentSum : sum(n: n-1, currentSum: currentSum + n) }
func sum (n: Int, currentSum: Int = 0) -> Int {
return n == 0 ? currentSum :
sum(n: n-1,
currentSum: currentSum + n)
}
我期望编译器使用尾部递归优化。但是我陷入了一个(字面意思是:-P)堆栈溢出问题。是否有任何标志,我需要设置,使编译器做这样的优化,我犯了任何错误,我的代码或这个编译器优化是不可用的?谢谢!
kd3sttzy1#
正如Martin所指出的,除非您打开优化器(-O),否则您在任何情况下都不会获得TCO,但即使在这种情况下,也无法保证您将获得TCO,因此您真的不能依赖它。Swift对递归算法不是特别友好。通常情况下,你会这样写:
-O
func sum(n: Int) -> Int { return (1...n).reduce(0, +) }
func sum(n: Int) -> Int {
return (1...n).reduce(0, +)
或者保持相同的计算模式(即从n到1倒计时):
func sum(n: Int) -> Int { return (1...n).reversed().reduce(0, +)}
return (1...n).reversed().reduce(0, +)
plicqrtu2#
是否有任何标志,我需要设置,使编译器做这样的优化,我犯了任何错误,我的代码或这个编译器优化是不可用的?一般来说,由于选择了自动引用计数(ARC)来进行内存管理,所以你不能依赖Swift中的尾部调用优化。如果一个函数需要释放内存,那么编译器会在函数的末尾插入代码。从而防止尾部调用位置中的调用被编译为尾部调用。
2条答案
按热度按时间kd3sttzy1#
正如Martin所指出的,除非您打开优化器(
-O
),否则您在任何情况下都不会获得TCO,但即使在这种情况下,也无法保证您将获得TCO,因此您真的不能依赖它。Swift对递归算法不是特别友好。通常情况下,你会这样写:或者保持相同的计算模式(即从n到1倒计时):
plicqrtu2#
是否有任何标志,我需要设置,使编译器做这样的优化,我犯了任何错误,我的代码或这个编译器优化是不可用的?
一般来说,由于选择了自动引用计数(ARC)来进行内存管理,所以你不能依赖Swift中的尾部调用优化。
如果一个函数需要释放内存,那么编译器会在函数的末尾插入代码。从而防止尾部调用位置中的调用被编译为尾部调用。