What is the advantage of nesting functions (generally speaking in Swift)
I am just learning Swift and I came across a section that talks about nesting functions:
Functions can be nested. Nested functions have access to variables declared in the outer function. You can use nested functions to organize your code into a long or complex function.
From here
So, if the intended benefit is "code organization", why not just nest the nested function independently of the outer function? It seems more organized to me.
The only advantage I can discern is that you "have access to variables declared in an outer function", but that seems trivial compared to the mess of having nested functions.
Any thoughts?
source to share
So, if the intended benefit is "code organization", why not just nest the nested function independently of the outer function? It seems more organized to me.
Oh, I totally disagree. If the only place the second function is required is inside the first function, keeping it inside the first function is much more organized.
Real life examples here: http://www.apeth.com/swiftBook/ch02.html#_function_in_function
In addition, a function within a function has a local environment in scope. Code inside a nested function can "see" local variables declared before the nested function is declared. This can be much more convenient and natural than passing multiple parameters.
However, the main thing that a local function allows you to do that you couldn't easily do in some other way is that you can form a function in real time (because a function is a closure) and return it from an external function.
http://www.apeth.com/swiftBook/ch02.html#_function_returning_function
source to share
IMO, the only difference between closures and nested functions is recursion. You can pass a function directly into the function body without the trick.
func a() {
func b() {
b() // Infinite loop!
}
b()
}
The captured object of the reference type dies when the dying person dies. In this case, the capture is a function of the lexical scope. This means that the function will die when it finishes executing.
Technically, the reference loop does this and is usually discouraged. But it can be helpful if you use it wisely.
For example combine this with asynchronous operations.
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)
}
It can simplify resource management in the execution of a coroutine without an explicit object instance. The resources are simply committed to the function spawnAsyncOp1
and will be released when the function dies.
source to share