Tricky output-based questions on Closures — Part III
2 min readMay 1, 2024
func makeCounter() -> () -> Int {
var count = 0
return {
defer { count += 1 }
return count
}
}
let counter = makeCounter()
print(counter())
print(counter())
Output Explanation:
- The
makeCounter
function returns a closure that increments and returns a counter value. - The
defer
statement defers the execution of thecount += 1
statement until the end of the closure's scope. - So, when
counter
is called twice, it first returns0
and then1
. - So, the output will be:
0
,1
.
func repeatClosure(_ closure: () -> Void, times: Int) {
for _ in 0..<times {
closure()
}
}
var counter = 0
let incrementCounter = { counter += 1 }
repeatClosure(incrementCounter, times: 3)
print(counter)
Output Explanation:
- The
repeatClosure
function repeats the given closuretimes
number of times. - Inside the closure, the
counter
variable is incremented by1
. - After calling
repeatClosure
withincrementCounter
as the closure and repeating it3
times, the value ofcounter
will be3
. - So, the output will be:
3
.
func generateClosures() -> [() -> Int] {
var closures: [() -> Int] = []
for i in 1...3 {
closures.append { i }
}
return closures
}
let closures = generateClosures()
let results = closures.map { $0() }
print(results)
Output Explanation:
- This code snippet creates an array of closures that each return the current value of
i
. - However, since
i
is captured by reference in the closures, they all share the same value. - At the time the closures are executed (when
map
is called), the value ofi
will be4
because it's the value that completes the loop. - So, the output will be:
[4, 4, 4]
.
func performOperation(_ operation: () -> Void) {
print("Before operation")
operation()
print("After operation")
}
func createClosure(_ value: Int) -> () -> Void {
return {
print(value)
}
}
let closure1 = createClosure(10)
let closure2 = createClosure(20)
performOperation(closure1)
performOperation(closure2)
Output Explanation:
- The
createClosure
function returns a closure that captures and prints thevalue
parameter. - When
closure1
is executed insideperformOperation
, it prints the captured value ofvalue
, which is10
. - Similarly, when
closure2
is executed insideperformOperation
, it prints the captured value ofvalue
, which is20
. - So, the output will be:
Before operation
10
After operation
Before operation
20
After operation
var result = 0
let closure1 = { result += 10 }
let closure2 = { [result] in print(result) }
closure1()
closure2()
Output Explanation:
closure1
modifies theresult
variable directly.closure2
capturesresult
as a constant at the time of its creation.- When
closure1
is called, it modifiesresult
to10
. - When
closure2
is called, it prints the captured value ofresult
, which is0
because it was captured beforeclosure1
executed. - So, the output will be:
0
.