I noticed when writing an assert
in Swift that the first value is typed as
@autoclosure() -> Bool
with an overloaded method to return a generic T
value, to test existence via the LogicValue
protocol
.
However sticking strictly to the question at hand. It appears to want an @autoclosure
that returns a Bool
.
Writing an actual closure that takes no parameters and returns a Bool does not work, it wants me to call the closure to make it compile, like so:
assert({() -> Bool in return false}(), "No user has been set", file: __FILE__, line: __LINE__)
However simply passing a Bool works:
assert(false, "No user has been set", file: __FILE__, line: __LINE__)
So what is going on? What is @autoclosure
?
Edit: @auto_closure
was renamed @autoclosure
It's just a way to get rid of the curly braces in a closure call, simple example:
Consider a function that takes one argument, a simple closure that takes no argument:
To call this function, we have to pass in a closure
If we omit the braces, we are passing in an expression and that's an error:
@autoclosure
creates an automatic closure around the expression. So when the caller writes an expression like2 > 1
, it's automatically wrapped into a closure to become{2 > 1}
before it is passed tof
. So if we apply this to the functionf
:So it works with just an expression without the need to wrap it in a closure.
Here's a practical example — my
print
override (this is Swift 3):When you say
print(myExpensiveFunction())
, myprint
override overshadows Swift'sprint
and is called.myExpensiveFunction()
is thus wrapped in a closure and not evaluated. If we're in Release mode, it will never be evaluated, becauseitem()
won't be called. Thus we have a version ofprint
that doesn't evaluate its arguments in Release mode.Description of auto_closure from the docs:
And here's the example apple uses along with it.
Basically what it means is you pass a boolean expression as that first argument instead of a closure and it automatically creates a closure out of it for you. That's why you can pass false into the method because it is a boolean expression, but can't pass a closure.
This shows a useful case of
@autoclosure
https://airspeedvelocity.net/2014/06/28/extending-the-swift-language-is-cool-but-be-careful/