by Hwee-Boon Yar — Subscribe to tips via weekly email

Swift provides the @autoclosure declaration attribute. When applied to a function parameter type, it converts the call site expression into a no-arg closure with a return value, delaying the evaluation of the expression. For example, in the following code, both normalFunction() and withAutoClosure() are called with the output of foo() , but because withAutoClosure() 's argument is declared as @autoclosure , it doesn't evaluate foo() . Instead the foo() call is wrapped into a closure which is then passed to withAutoClosure() .

func foo() -> Int { print("foo called") return 1 } func normalFunction(_ i: Int) { print("normalFunction:") print(" Value returned by foo: \(i)

") } func withAutoClosure(_ fn: @autoclosure ()->Int) { print("withAutoClosure:") // print("value returned: \(fn())") print(" Notice foo is not called?") } normalFunction(foo()) withAutoClosure(foo())

This will produce the output:

foo called normalFunction: Value returned by foo: 1 withAutoClosure: Notice foo is not called?

Using @autoclosure , you can decide to skip the evaluating the expression or evaluate it one or more times. The Swift blog gives an example of implementing assert() using @autoclosure , as well as short-circuiting logical operators.

Note that @autoclosure has to be used judiciously because the someone reading the code cannot easily determine that the argument has @autoclosure applied to it.

PS: This code is written in Swift 3. Minor modifications would make it work with Swift 2.2

PPS: If you have any interesting (and short) tip you would to share or a feature you would like me to talk about, reply to this email





Your feedback is valuable: Do you want more nuggets like this? Yes or No

.

.