Bird
Raised Fist0
Swiftprogramming~10 mins

Autoclosures (@autoclosure) in Swift - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Autoclosures (@autoclosure)
Call function with expression
↓
@autoclosure wraps expression
↓
Function receives closure
↓
Closure executed inside function
↓
Expression evaluated now
↓
Function returns result
The @autoclosure attribute wraps an expression into a closure automatically, delaying its evaluation until used inside the function.
Execution Sample
Swift
func logIfTrue(_ predicate: @autoclosure () -> Bool) {
    if predicate() {
        print("It's true!")
    }
}

logIfTrue(2 > 1)
This code delays evaluating '2 > 1' until inside the function, then prints if true.
Execution Table
StepActionExpression/ConditionClosure Called?Output
1Call logIfTrue with 2 > 12 > 1No
2@autoclosure wraps '2 > 1' into closureClosure createdNo
3Inside function, call predicate()Evaluate 2 > 1Yes
4Condition is truetrueYesIt's true! printed
5Function ends
💡 Function ends after printing because condition is true
Variable Tracker
VariableStartAfter Step 2After Step 3Final
predicatenoneclosure wrapping '2 > 1'closure called, evaluates to trueclosure called, true
Key Moments - 2 Insights
Why isn't the expression '2 > 1' evaluated immediately when calling the function?
Because @autoclosure wraps the expression into a closure, delaying evaluation until predicate() is called inside the function (see execution_table step 2 and 3).
What happens if the closure is never called inside the function?
The expression is never evaluated, so no output or side effects occur (see execution_table step 1 and 2 where closure is created but not called).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, at which step is the expression '2 > 1' actually evaluated?
AStep 3
BStep 1
CStep 2
DStep 5
💡 Hint
Check the 'Closure Called?' column where evaluation happens inside the function.
According to the variable tracker, what does 'predicate' hold after step 2?
AThe boolean value true
BAn integer value
CA closure wrapping '2 > 1'
DNothing (nil)
💡 Hint
Look at the 'After Step 2' column for 'predicate' in variable_tracker.
If the function never calls predicate(), what will be the output?
AIt prints "It's false!"
BNo output
CIt prints "It's true!"
DCompilation error
💡 Hint
See key_moments about what happens if closure is not called.
Concept Snapshot
Syntax: Use @autoclosure before a function parameter.
Behavior: Wraps an expression into a closure automatically.
Evaluation: Expression is delayed until closure is called inside the function.
Use: Simplifies syntax for delayed evaluation without explicit closure syntax.
Example: func f(_ p: @autoclosure () -> Bool) { if p() { ... } }
Full Transcript
Autoclosures in Swift let you pass an expression to a function without writing a closure explicitly. The expression is wrapped automatically into a closure and only evaluated when the function calls it. This delays evaluation and can improve readability. In the example, calling logIfTrue(2 > 1) does not evaluate '2 > 1' immediately. Instead, the expression is wrapped into a closure by @autoclosure. Inside the function, calling predicate() runs the expression and returns true, so the message prints. If the closure is never called, the expression is never evaluated and no output occurs. This helps avoid unnecessary work or side effects until needed.

Practice

(1/5)
1. What does the @autoclosure attribute do in Swift?
easy
A. Converts a closure into a normal function
B. Forces immediate execution of a closure parameter
C. Automatically wraps an expression into a closure to delay its execution
D. Prevents a closure from capturing variables

Solution

  1. Step 1: Understand the purpose of @autoclosure

    @autoclosure automatically wraps an expression passed as an argument into a closure, delaying its execution until called.
  2. Step 2: Compare with other options

    Options B, C, and D describe behaviors unrelated to @autoclosure's purpose.
  3. Final Answer:

    Automatically wraps an expression into a closure to delay its execution -> Option C
  4. Quick Check:

    @autoclosure delays execution = A [OK]
Hint: Autoclosure delays code execution by wrapping it automatically [OK]
Common Mistakes:
  • Thinking @autoclosure runs code immediately
  • Confusing @autoclosure with normal closures
  • Assuming it changes closure syntax
2. Which of the following is the correct way to declare a function parameter using @autoclosure in Swift?
easy
A. func check(_ condition: @autoclosure () -> Bool) { }
B. func check(@autoclosure condition: Bool) { }
C. func check(condition: @autoclosure Bool) { }
D. func check(_ condition: Bool @autoclosure) { }

Solution

  1. Step 1: Recall correct syntax for @autoclosure

    The correct syntax places @autoclosure before the closure type: @autoclosure () -> Bool.
  2. Step 2: Analyze each option

    func check(_ condition: @autoclosure () -> Bool) { } matches the correct syntax. Options A, B, and C misuse the attribute placement or type declaration.
  3. Final Answer:

    func check(_ condition: @autoclosure () -> Bool) { } -> Option A
  4. Quick Check:

    @autoclosure syntax = func check(_ condition: @autoclosure () -> Bool) { } [OK]
Hint: Remember: @autoclosure before closure type () -> Type [OK]
Common Mistakes:
  • Placing @autoclosure after the type
  • Using @autoclosure on non-closure types
  • Omitting the closure arrow syntax
3. What will be the output of the following Swift code?
func logIfTrue(_ predicate: @autoclosure () -> Bool) {
    if predicate() {
        print("True")
    } else {
        print("False")
    }
}

logIfTrue(3 > 5)
medium
A. True
B. Runtime crash
C. Compile-time error
D. False

Solution

  1. Step 1: Understand the function behavior

    The function takes a condition as an autoclosure and calls it inside the if statement.
  2. Step 2: Evaluate the passed expression

    The expression 3 > 5 is false, so predicate() returns false, triggering the else branch.
  3. Final Answer:

    False -> Option D
  4. Quick Check:

    3 > 5 is false, so output = False [OK]
Hint: Evaluate the expression inside autoclosure when called [OK]
Common Mistakes:
  • Assuming autoclosure runs immediately before function call
  • Confusing true/false logic
  • Expecting compile errors due to autoclosure
4. Identify the error in this Swift function using @autoclosure:
func execute(_ action: @autoclosure () -> Void) {
    action
}

execute(print("Hello"))
medium
A. Missing parentheses to call the closure inside the function
B. Incorrect use of @autoclosure on a Void return type
C. Cannot pass print statement as autoclosure
D. Function parameter should not be marked @autoclosure

Solution

  1. Step 1: Check how the closure is called inside the function

    The parameter action is a closure and must be called with parentheses: action().
  2. Step 2: Identify the error

    The code uses action without parentheses, so the closure is not executed, causing no output.
  3. Final Answer:

    Missing parentheses to call the closure inside the function -> Option A
  4. Quick Check:

    Closure must be called with () = Missing parentheses to call the closure inside the function [OK]
Hint: Call autoclosure with () to execute it inside function [OK]
Common Mistakes:
  • Forgetting to call the closure with parentheses
  • Thinking @autoclosure forbids Void closures
  • Assuming print can't be autoclosure
5. Consider this Swift code using @autoclosure to log messages only when needed:
func log(_ message: @autoclosure () -> String, onlyIf condition: Bool) {
    if condition {
        print(message())
    }
}

log("Debug info", onlyIf: false)

What is the main benefit of using @autoclosure here?
hard
A. The function runs faster because closures are always synchronous
B. The message string is constructed only if the condition is true, saving resources
C. The message is printed twice automatically
D. The condition parameter becomes optional

Solution

  1. Step 1: Understand how @autoclosure delays evaluation

    The message string expression is wrapped in a closure and only evaluated when message() is called.
  2. Step 2: Analyze the condition effect

    Since condition is false, message() is never called, so the string is not constructed, saving computation.
  3. Final Answer:

    The message string is constructed only if the condition is true, saving resources -> Option B
  4. Quick Check:

    @autoclosure delays message creation = The message string is constructed only if the condition is true, saving resources [OK]
Hint: Autoclosure delays expensive expressions until needed [OK]
Common Mistakes:
  • Thinking message is always created regardless of condition
  • Assuming autoclosure prints automatically
  • Confusing condition with message parameter
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard