@autoclosure what, why and when
Let’s say “Good morning” to John and Pavel:
The output is “Good morning, Pavel”. For John the first parameter is false and so, no greeting printed for him:
Let’s say “Good morning” to Robert:
This time goodMorning function is called with another function, giveAname, as the second parameter. This giveAname function return a String. It allows using it as a second parameter for goodMorning:
Let’s pass false as the first parameter: no “Good morning” for Robert. But the output window shows that giveAname function anyway:
Expected: call giveAname() to get a string and pass this string to goodMorning. The first parameter is false and so the second parameter is unused for this case. But function giveAname is called.
If I do not want giveAname to be called I should use a closure:
The closure as the second parameter changed the order: now giveAname is not called before the goodMorning call. Funtion giveAname is called later and only if it’s needed.
But… Now the second parameter is the closure of a specific type. The function goodMorning does not accept a String constant or a variable now.
@autoclosure attribute added before the second parameter type opens all these possibilities. Let’s call goodMorning with a constant, variable or a closure:
The output says that giveAname was called (the first parameter is true again for Robert) and “Good morning” for Robert and Pavel:
@autoclosure can be useful. For example, here is an assert function:
func assert(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String)
Both parameters can be constants, variables or closures:
Let’s change this assert function to work only if the debugging is allowed:
In the real life it looks a bit more complicated, but means the same:
public func assert(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = #file, line: UInt = #line)
1. Parameter in a function can be replaced with a closure that takes no parameter and returns back a value of the same type as the parameter.
2. Such closure parameter can be marked with an @autoclosure attribute.
3. No need to put braces around such @autoclosure-d parameter. Value, another function or an expression passed is wrapped with braces automatically.
4. Another function used as that marked closure parameter is not executed until it will be called explicitly from the function body.