func biggerOne(_ a : Int, _ b : Int) -> Int? {
if a == b {
return nil
} else if a > b {
return a
} else {
return b
}
}
var someClosure : (Int, Int) -> Int? = biggerOne(_:_:)
// Not working
someClosure = { (left : Int, right : Int) in
someClosure(left , right)
}
print(someClosure(2,3)!)
// Working
someClosure = { [someClosure] (left : Int, right : Int) in
someClosure(left , right)
}
print(someClosure(2,3)!)
I knew that closure uses capture list to store values ββon creation so can solve the problem but why is the code above not working?
If you have any ideas, I would appreciate your help.
2
Answers
There are circular references,
someClosure
is calling itself.Try eliminating the circular references:
Without capturing,
someClosure
here is simply calling itself, and then causing a stack overflow:(I’m not sure if the fact that this passes compilation is intentional.)
This is just like as if you have defined a named function like:
On the other hand, the capture list captures the old value of
someClosure
, so "someClosure
" inside the closure body refers to the captured value (i.e. the old value), and there is no infinite recursion. You can think of this as:Using
lldb yourExecutable
and thethread backtrace
command, you can see the many duplicated stack frames that are caused by the recursion.