J'ai remarqué lors de l'écriture d'un assert
Swift que la première valeur est tapée comme
@autoclosure() -> Bool
avec une méthode surchargée pour renvoyer une T
valeur générique , pour tester l'existence via le LogicValue
protocol
.
Cependant s'en tenir strictement à la question à l'étude. Il semble vouloir un @autoclosure
qui renvoie un Bool
.
L'écriture d'une fermeture réelle qui ne prend aucun paramètre et retourne un booléen ne fonctionne pas, cela veut que j'appelle la fermeture pour la faire compiler, comme ceci:
assert({() -> Bool in return false}(), "No user has been set", file: __FILE__, line: __LINE__)
Cependant, le simple fait de passer un Bool fonctionne:
assert(false, "No user has been set", file: __FILE__, line: __LINE__)
Alors, quoi de neuf? C'est quoi @autoclosure
?
Edit: a @auto_closure
été renommé@autoclosure
f({2 >1}())
f(2 > 1)
fonctionne. L'appelf({2 > 1})
échoue avecerror: function produces expected type 'Bool'; did you mean to call it with '()'?
. Je l'ai testé dans une aire de jeux et avec le Swift REPL.func f(@autoclosure pred: () -> Bool)
Voici un exemple pratique - mon
print
remplacement (c'est Swift 3):Quand vous dites
print(myExpensiveFunction())
, maprint
priorité éclipse celle de Swiftprint
et est appelée.myExpensiveFunction()
est ainsi enveloppé dans une fermeture et non évalué . Si nous sommes en mode Release, il ne sera jamais évalué, caritem()
il ne sera pas appelé. Nous avons donc une version deprint
qui n'évalue pas ses arguments en mode Release.la source
myExpensiveFunction()
?. Si au lieu d'utiliser l'autoclosure vous transmettez la fonction pour imprimer commeprint(myExpensiveFunction)
, quel en serait l'impact? Merci.Description de auto_closure dans la documentation:
Et voici l'exemple que Apple utilise avec lui.
Fondamentalement, cela signifie que vous passez une expression booléenne comme premier argument au lieu d'une fermeture et que cela crée automatiquement une fermeture pour vous. C'est pourquoi vous pouvez passer false dans la méthode car il s'agit d'une expression booléenne, mais ne peut pas passer de fermeture.
la source
@auto_closure
ici. Le code fonctionne très bien sans elle:func simpleAssert(condition: Bool, message: String) { if !condition { println(message) } }
. À utiliser@auto_closure
lorsque vous devez évaluer un argument à plusieurs reprises (par exemple, si vous implémentez unewhile
fonction semblable à celle-ci) ou lorsque vous devez retarder l'évaluation d'un argument (par exemple, si vous implémentez un court-circuit&&
).autoclosure
avec unewhile
fonction semblable à celle-ci? Je ne semble pas comprendre cela. Merci d'avance.Cela montre un cas utile de
@autoclosure
https://airspeedvelocity.net/2014/06/28/extending-the-swift-language-is-cool-but-be-careful/la source
C'est juste un moyen de se débarrasser des accolades lors d'un appel de fermeture, exemple simple:
la source
@autoclosure
est un paramètre de fonction qui accepte une fonction cuisinée (ou un type retourné) tandis qu'un généralclosure
accepte une fonction bruteJetons un coup d'œil à l'exemple
la source