Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The @autoclosure attribute is a parameter declaration modifier in Swift that automatically wraps an expression passed as an argument into a parameterless closure. It provides syntactic sugar by allowing the caller to omit the explicit closure braces {} at the call site, while preserving the deferred execution semantics inherent to closures.

Syntax and Mechanics

When a function parameter is annotated with @autoclosure, the Swift compiler intercepts the passed expression and encapsulates it within a closure of type () -> T, where T is the return type of the expression.
// Standard closure parameter
func standardClosure(_ predicate: () -> Bool) {
    _ = predicate()
}
standardClosure({ 5 > 3 }) // Requires explicit braces

// Autoclosure parameter
func autoClosure(_ predicate: @autoclosure () -> Bool) {
    let result = predicate()
    print(result)
}
autoClosure(5 > 3) // Braces are omitted; compiler wraps the expression

Technical Constraints and Behavior

  • Signature Requirement: The attribute can only be applied to closures that take no arguments. Applying @autoclosure to a closure type that requires parameters (e.g., (Int) -> Bool) will result in a compiler error.
  • Deferred Evaluation: The expression passed as the argument is not evaluated at the time of the function call. Evaluation is strictly deferred until the closure is explicitly invoked within the function body. If the closure is never called, the expression is never evaluated.
  • Escaping Contexts: By default, closures created by @autoclosure are non-escaping. If the wrapped expression needs to outlive the scope of the function (e.g., stored in a property or executed asynchronously), the parameter must be annotated with both @autoclosure and @escaping.
var deferredOperations: [() -> Void] = []

// Requires @escaping to append to an external array
func queueOperation(_ operation: @autoclosure @escaping () -> Void) {
    deferredOperations.append(operation)
}

queueOperation(print("Operation queued"))
  • Error Handling: If the expression being wrapped can throw an error, the autoclosure must be marked with throws. The try keyword is placed at the call site of the function, not inside the omitted closure braces.
func someThrowingFunction() throws -> Int {
    return 42
}

func evaluateThrowing(_ expression: @autoclosure () throws -> Int) rethrows -> Int {
    return try expression()
}

// The 'try' is applied to the function call, but applies to the deferred expression
let result = try evaluateThrowing(someThrowingFunction())
print(result)
Master Swift with Deep Grasping Methodology!Learn More