嵌套函数有啥好处(一般/在 Swift 中)

Posted

技术标签:

【中文标题】嵌套函数有啥好处(一般/在 Swift 中)【英文标题】:What is the benefit of nesting functions (in general/in Swift)嵌套函数有什么好处(一般/在 Swift 中) 【发布时间】:2015-08-01 23:42:11 【问题描述】:

我刚刚学习了一些 Swift,我遇到了讨论嵌套函数的部分:

函数可以嵌套。嵌套函数可以访问在外部函数中声明的变量。您可以使用嵌套函数来组织较长或复杂的函数中的代码。

来自here

因此,如果所谓的好处是“组织代码”,为什么不在外部函数之外独立地拥有嵌套函数呢?对我来说,这似乎更有条理。

我能看出的唯一好处是您“可以访问在外部函数中声明的变量”,但这与嵌套函数的混乱相比似乎微不足道。

有什么想法吗?

【问题讨论】:

继续阅读直到你到达函数章节,然后你会发现好处:) 【参考方案1】:

因此,如果所谓的好处是“组织代码”,为什么不在外部函数之外独立地拥有嵌套函数呢?在我看来,这似乎更有条理。

哦,我完全不同意。如果需要第二个函数的唯一位置是在第一个函数中,那么将其保留在第一个函数中会更加更有条理。

此处的真实示例:http://www.apeth.com/swiftBook/ch02.html#_function_in_function

另外,函数中的函数在范围内具有本地环境。嵌套函数内的代码可以“看到”在嵌套函数声明之前声明的局部变量。这比传递一堆参数要方便和自然得多。

然而,一个本地函数可以让你做而你无法以任何其他方式轻易做到的 key 事情是你可以实时形成函数(因为函数是一个闭包)并从外部函数返回。

http://www.apeth.com/swiftBook/ch02.html#_function_returning_function

【讨论】:

嗯,这很简单。感谢您强调这一点! (将在 6 分钟内标记正确答案) @matt 我完全同意你的看法;我唯一关心的是函数主体的大小以及父函数声明与其实际主体之间的差距。假设我们在一个函数中有 3-5 个辅助函数(局部函数),它们需要在函数顶部声明;所以读者必须滚动很多行才能到达实际的正文;你对这种情况有什么建议?我们应该把这个函数提取为一个新的类吗? @matt 不,我想我可能误解了这个案子。示例截图:dropbox.com/s/lzepxqxujrth4yf/…。我关心的是父函数,这里是 convertToParams 以及它的签名和它的实际主体之间的差距(MARK:convertToParams body)我真的很喜欢打包函数来帮助函数在函数内部完成它的工作;但是这个问题,你必须从签名滚动到实际的身体有点让我担心它的可读性。它可能需要更多功能。你有什么建议?【参考方案2】:

一个非常好的事情是 Xcode 将在函数弹出窗口中缩进其父函数中的嵌套函数。函数弹出窗口使用与重新计算缩进布局相关的函数导航更容易,所有这些函数都集中在一个位置。

【讨论】:

【参考方案3】:

IMO,闭包和嵌套函数的唯一区别是递归。您可以在函数体中引用函数本身而无需任何技巧。

func a() 
    func b() 
        b() // Infinite loop!
    
    b()

当捕获者死亡时,被捕获的引用类型对象也随之死亡。在这种情况下,捕获器是函数的词法范围。这意味着函数在执行完毕后就会死掉。

从技术上讲,这会产生一个引用循环,通常不鼓励这样做。但是,如果您明智地使用它,它会很有用。

例如,将它与异步操作结合起来。

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 中捕获,并在函数终止时释放。

【讨论】:

以上是关于嵌套函数有啥好处(一般/在 Swift 中)的主要内容,如果未能解决你的问题,请参考以下文章

基于元组或嵌套字典有啥好处吗?

PHP 嵌套函数有啥用?

swift中嵌套函数的实际用途是啥? [复制]

函数——基本语法,嵌套匿名高阶递归函数

init 函数中的 Swift 嵌套类型

Swift 中的高阶函数和函数嵌套