How to handle closure recursivity

后端 未结 5 1357
栀梦
栀梦 2020-12-19 00:40

Here\'s a very simple recursive function:

func lap (n: Int) -> Int {
    if n == 0 { return 0 }
   return lap (n - 1)
}

If I want to con

5条回答
  •  自闭症患者
    2020-12-19 01:20

    EDIT This has been resolved with Swift 2 using nested functions. Apple suggests this code:

    func f(n: Int) {
        func lap(n: Int) -> Int {
            if n == 0 { return 0 }
            print(n)
            return lap(n - 1)
        }
        lap(n)
    }
    
    for i in 0..<1000000 { f(i) }
    

    Although this is not obvious from the current example, so-called local functions capture the locals of the enclosing scope.

    Using a location function does not leak, whereas a closure would. However, clearly, lap can't be reassigned in this case.

    I received an email from Apple's Joe Groff stating that they still plan on making it possible to capture closures as weak and mutable variables at a later point. This does confirm, however, that there's no way to do it right now except with a local function.


    Your current solution has a memory leak in it: lap's closure has a strong reference to itself, meaning that it cannot ever be released. This can easily be verified by launching the following program with the Leaks instrument attached:

    import Foundation
    
    func f(n: Int) {
        var lap: (Int)->Int = { $0 }
        lap = {
            (n: Int) -> Int in
            if n == 0 { return 0 }
            println(n)
            return lap (n - 1)
        }
        lap(n)
    }
    
    for i in 0..<1000000 {
        f(i)
    }
    

    Unfortunately, as the explicit capture syntax cannot be applied to closure types (you get an error that says "'unowned' cannot be applied to non-class type '(Int) -> Int'"), there appears to be no easy way to achieve this without leaking. I filed a bug report about it.

提交回复
热议问题