Tricky output-based questions on Closures — Part III

Janvi Arora
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 the count += 1 statement until the end of the closure's scope.
  • So, when counter is called twice, it first returns 0 and then 1.
  • 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 closure times number of times.
  • Inside the closure, the counter variable is incremented by 1.
  • After calling repeatClosure with incrementCounter as the closure and repeating it 3 times, the value of counter will be 3.
  • 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 of i will be 4 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 the value parameter.
  • When closure1 is executed inside performOperation, it prints the captured value of value, which is 10.
  • Similarly, when closure2 is executed inside performOperation, it prints the captured value of value, which is 20.
  • 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 the result variable directly.
  • closure2 captures result as a constant at the time of its creation.
  • When closure1 is called, it modifies result to 10.
  • When closure2 is called, it prints the captured value of result, which is 0 because it was captured before closure1 executed.
  • So, the output will be: 0.

--

--

No responses yet