I’m studying closures and saw a unknown (for me) example of the use of closures in function in the book:
func counter() -> () -> Int {
var count = 0
let incrementer: () -> Int = {
count += 1
return count
}
return incrementer
}
But I’ve never seen such a way of creating a closure. I’ve tried the usual one method and that worked too:
func counter() -> Int {
var count = 0
let incrementer = { () -> Int in
count += 1
return count
}
return incrementer()
}
Can you please explain to me how it works? Is it just a type annotation?
>Solution :
Yes, the code you provided uses a closure in a way that might look a bit unusual at first glance, but it’s a valid and common usage of closures in Swift. What you’re seeing here is the use of type annotations to explicitly specify the type of a closure, and then that closure is returned from the counter
function. Let’s break it down step by step:
-
func counter() -> () -> Int
: This function signature indicates that thecounter
function returns a closure that takes no arguments() -> Int
. In other words, it returns a function that takes no input and returns an integer. -
Inside the
counter
function, there’s a variablecount
initialized to 0. Thiscount
variable is captured by the closure defined within the function. -
let incrementer: () -> Int = { ... }
: Here, a closure is defined and assigned to theincrementer
constant. This closure has no parameters (()
) and returns an integer (Int
). The closure body increments thecount
variable and returns its current value. -
Finally, the
incrementer
closure is returned from thecounter
function. So, when you callcounter()
, it returns a closure that you can then call to increment and retrieve the current value ofcount
.
You can use this counter
function like this:
let myCounter = counter()
print(myCounter()) // 1
print(myCounter()) // 2
print(myCounter()) // 3
Each time you call myCounter()
, it invokes the closure, increments the count
variable, and returns the updated value.
In contrast, the second approach you provided is also valid and achieves the same result. It defines the closure and immediately invokes it. It’s just a different way of using closures to achieve the same behavior. The choice between these two approaches depends on your specific use case and coding style preferences.