分享
三行代码  ›  专栏  ›  技术社区  ›  Andre Liberty

闭包如何捕获值类型?

  •  0
  • Andre Liberty  · 技术社区  · 1 周前

    var cl: (() -> ())! 
    func foo() { 
        var x = 20
        cl = { 
          print(x)
        }
    
    }
    foo()
    cl() // prints 20
    

    x 是一个 Int foo 退货 应该消失。遵循上述推理 不应该存在的时候 cl 被称为,但它仍然打印 20 . 有人能解释一下 在这种情况下,并保持在记忆中。
    在这种情况下有捕获列表。在捕获列表的情况下,这是显而易见的,因为使用捕获列表捕获值类型只是创建一个捕获值的副本。

    1 回复  |  直到 1 周前
        1
  •  1
  •   matt aiwiguna    1 周前

    有人能解释一下闭包在这种情况下是如何捕获x并将其保存在内存中的吗。

    其实没有“怎么做”。这就是一个结束 捕获 x 当局部引用超出范围时不会消亡,因为闭包已经捕获了它并继续存在;因此 foo 在一个不可见的“闭包捕获”空间中运行,属于这个闭包,只要闭包本身持续存在。

    闭包的这种能力使闭包成为闭包。

    这个功能的一个特性是您的示例没有得到,即捕获的引用仍然是 可写的 var ). 例如:

    var cl: (() -> ())!
    func foo() {
        var x = 20
        cl = {
          print(x)
          x += 1
        }
    
    }
    foo()
    cl() // prints 20
    cl() // prints 21
    

    因此,我们能够在封闭捕获世界中保持关闭状态。

    起初的

    var cl: (() -> ())!
    var x = 20
    func foo() {
        cl = {
          print(x)
          x += 1
        }
    
    }
    foo()
    cl() // prints 20
    cl() // prints 21
    print(x) // 22