swift - 为什么递归 swift 函数定义不会对其初始“值”产生问题?
问题描述
这里有很多关于尝试在 Swift 中定义递归闭包的有趣问题。我认为答案最清晰的是这篇文章,询问为什么不能在 Swift 的同一行中声明和定义递归闭包。但是,他们不会问相反的问题。也就是说,如果我不能创建这样的代码:
var countdown = { i in
print(i)
if i > 1 {
countdown(i - 1)
}
}
// error: Variable used within its own initial value
那为什么我可以写这样的代码:
func countdown(_ i: Int) {
print(i)
if i > 1 {
countdown(i - 1)
}
}
函数有什么特别之处,使它们在尝试在自己的声明中调用自己时没有任何问题?我理解闭包背后的问题:它试图捕获一个尚不存在的值(闭包本身)。但是,我不明白为什么该功能没有同样的问题。查看Swift Book,我们看到:
全局函数是具有名称且不捕获任何值的闭包。
这是一个半答案:上面的函数不会引起问题,因为函数不会捕获值。但是,如果函数不捕获值(尤其是递归值),它们如何工作?
解决方案
不太确定你在寻找什么答案。我的意思是,一个简单的答案是 Swift 编译器就是这样工作的。
一个原因可能是使用func
表达式,例如func countdown(...) {}
,编译器可以安全地假设该函数将在它调用自身时定义。
而对于变量定义(即变量获取其值的表达式),它通常不会做出这样的假设,因为类似
var c = c + 1
由于相同的“在其自己的初始值中使用的变量”错误,显然无法正常工作。
话虽如此,编译器可能已经对闭包类型变量的定义进行了特殊定义,因为与非闭包变量不同,在定义它们时不需要它们的实际值。
这就是为什么一个解决方案是定义变量(或者至少重新向编译器保证它会被定义!
),所以编译器不会抱怨:
var countdown: ((Int) -> Void)!
countdown = { i in
print(i)
if i > 1 {
countdown(i - 1)
}
}
推荐阅读
- python - 拒绝抽样没有给出正确的分布
- c++ - 如何在 C++ 中访问 LPCWSTR 映射的值
- python - 币安python获取api
- java - 线程“AWT-EventQueue-0”java.lang.AbstractMethodError 中的异常:
- java - 我们可以同时在 Android 设备和 Android 模拟器上运行 appium 测试吗?
- fetch-api - 使用 Fetch API 和 PHP 文件获取文本响应
- highlight - 突出价值差异
- ios - 无法使用 Delphi 10.4.2 for iOS iPhone APP 更改启动屏幕
- python - 按批次条件计算相关系数
- node.js - 为什么我的第一个查询很慢但是很快?