Achtergrond van de vraag:
@autoclosure is een speciale modifier in Swift die het mogelijk maakt om automatisch een closure te creëren uit een expressie die als functieargument is doorgegeven. Het verscheen voor het eerst om de syntaxis te vereenvoudigen en de leesbaarheid te verhogen bij het schrijven van assert/guard-expressies en uitgestelde berekeningen van waarden.
Probleem:
Standaard closures vereisen expliciete syntaxis ({ ... }). Dit is vaak overbodig wanneer de logica eenvoudig is (bijvoorbeeld bij luiere controles). Maar bij het gebruik van autoclosure kan het voor de ontwikkelaar onopgemerkt blijven dat het tijdstip van uitvoering van de code verandert of dat de waarde van de side-effect expressie verloren gaat. Bovendien accepteert autoclosure geen parameters.
Oplossing:
@autoclosure maakt het mogelijk om beknopt te schrijven:
Voorbeeld code:
func logIfTrue(_ predicate: @autoclosure () -> Bool) { if predicate() { print("Voorwaarde voldaan") } } // Zonder autoclosure: logIfTrue({ 2 > 1 }) // Met autoclosure: logIfTrue(2 > 1)
Belangrijke kenmerken:
Kan autoclosure parameters accepteren?
Nee. Autoclosure is altijd contextloos: het accepteert 0 parameters en "omvat" eenvoudig de expressie.
Wat is het verschil tussen de types () -> T en @autoclosure () -> T?
Een gewone closure vereist expliciete syntaxis - autoclosure maakt het mogelijk om een expressie door te geven zonder deze tussen accolades te plaatsen, wat een aanzienlijke impact heeft op de functieinterfaces.
Wat gebeurt er als autoclosure een side-effect heeft?
Autoclosure wordt alleen geëvalueerd bij aanroep - als de expressie een side-effect heeft, gebeurt dit strikt op het moment van aanroep en niet bij het doorgeven van de parameter aan de functie.
var x = 5 func change(_ value: @autoclosure () -> Int) { print(value()) } change(x += 1) // x wordt hier alleen verhoogd
Bij het implementeren van foutanalyses werden berichten geschreven via een functie die autoclosure gebruikte voor de melding. Maar de message-expressie had een side-effect (verzond een netwerkverzoek), waardoor de echte uitvoering niet in de volgorde plaatsvond die de ontwikkelaar verwachtte. Hierdoor werd de statistiek onjuist verzameld.
Voordelen:
Nadelen:
Gebruik van autoclosure in assert-methoden, waar het nodig is om de expressie alleen bij behoefte te evalueren of de syntaxis voor de eindgebruiker van de API te vergemakkelijken. De code wordt korter en er zijn geen side-effecten.
Voordelen:
Nadelen: