我刚刚学习了一些Swift,我遇到了关于嵌套函数的部分:
函数可以嵌套。嵌套函数可以访问外部函数中声明的变量。您可以使用嵌套函数来组织长或复杂函数中的代码。
来自here
因此,如果声称的好处是“组织代码”,为什么不在外部函数之外独立地使用嵌套函数?对我来说,这看起来更有条理。
我能辨别的唯一好处是你“可以访问在外部函数中声明的变量”,但与嵌套函数的混乱相比,这似乎微不足道。
有什么想法吗?
因此,如果声称的好处是“组织代码”,为什么不在外部函数之外独立地使用嵌套函数?对我来说,这看起来更有条理。
哦,我完全不同意。如果需要第二个函数的唯一位置在第一个函数内部,那么将它保持在第一个函数内部则更有条理。
现实生活中的例子:http://www.apeth.com/swiftBook/ch02.html#_function_in_function
另外,函数中的函数具有范围内的本地环境。嵌套函数内的代码可以“看到”嵌套函数声明之前声明的局部变量。这比传递一堆参数更方便和自然。
但是,本地函数允许您执行的任何其他方式无法轻松完成的关键是您可以实时形成函数(因为函数是闭包)并从外部函数返回它。
http://www.apeth.com/swiftBook/ch02.html#_function_returning_function
一个非常好的事情是Xcode将在函数弹出窗口中缩进其父函数中的嵌套函数。使用与重新计算布局缩进相关的函数和所有分组在一个地方的函数,更容易导航函数弹出窗口。
IMO,闭包和嵌套函数的唯一区别是递归。您可以在函数体中引用函数本身而无需技巧。
func a() {
func b() {
b() // Infinite loop!
}
b()
}
当捕获器死亡时,捕获的引用类型对象将死亡。在这种情况下,capturer是函数的词法范围。这意味着该函数在完成执行后将会死亡。
从技术上讲,这是一个参考周期,通常不鼓励。但如果您明智地使用它,这可能很有用。
例如,将其与异步操作结合使用。
func spawnAsyncOp1(_ completion: @escaping () -> Void) {
enum Continuation {
case start
case waitForSomethingElse1
case retry
case end
}
let someResource = SomeResource()
func step(_ c: Continuation) {
switch c {
case .start:
return step(.waitForSomethingElse1)
case .waitForSomethingElse1:
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(10), execute: {
let fc = (someResource.makeRandomResult() % 100 < 50) ? .end : .retry as Continuation
print("\(fc)")
return step(fc)
})
case .retry:
return step(.start)
case .end:
return completion()
}
}
return step(.start)
}
如果没有显式的对象实例,它可以使协程执行中的资源管理更简单。资源只是在函数spawnAsyncOp1
中捕获,并在函数死亡时释放。