How to handle closure recursivity

后端 未结 5 1360
栀梦
栀梦 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:32

    you can workaround it with two step assignment

    var lap : (Int) -> Int!
    lap = {
        (n: Int) -> Int in
        if n == 0 { return 0 }
        return lap(n - 1)
    }
    

    or you can use Y combinator

    func Y( f: (T -> R) -> (T -> R) ) -> (T -> R) {
        return { t in f(Y(f))(t) }
    }
    
    let lap = Y {
        (f : Int -> Int) -> (Int -> Int) in
        return { (n : Int) -> Int in return n == 0 ? 0 : f(n - 1) }
    }
    
    // with type inference 
    let lap2 = Y {
        f in { n in n == 0 ? 0 : f(n - 1) }
    }
    

    This is a workaround of the memory leak problem that @zneak found (It doesn't have memory leak but captured the wrong value)

    func f(n: Int) {
        var f = Foo()
        var lap: @objc_block (Int)->Int = { $0 }
        var obj: NSObject = reinterpretCast(lap)
        lap = {
            [weak obj] (n: Int) -> Int in // unowned will cause crush
            if n == 0 { return 0 }
            println(f)
            var lap2 : @objc_block (Int)->Int = reinterpretCast(obj)
            return lap2 (n - 1)
        }
        lap(n)
    }
    
    for i in 0..<5 {
        f(i)
    }
    
    class Foo {
        init() {
            println("init");
        }
    
        deinit {
            println("deinit")
        }
    }
    

提交回复
热议问题