Al escribir un assert
mensaje en Swift, noté que el primer valor se escribe como
@autoclosure() -> Bool
con un método sobrecargado para devolver un T
valor genérico , para probar la existencia a través de LogicValue
protocol
.
Sin embargo, apegarse estrictamente a la pregunta en cuestión. Parece querer un @autoclosure
que devuelve unBool
.
Escribir un cierre real que no toma parámetros y devuelve un Bool no funciona, quiere que llame al cierre para que se compile, así:
assert({() -> Bool in return false}(), "No user has been set", file: __FILE__, line: __LINE__)
Sin embargo, simplemente pasar un Bool funciona:
assert(false, "No user has been set", file: __FILE__, line: __LINE__)
¿Entonces qué está pasando? Que es@autoclosure
?
Editar: @auto_closure
fue renombrado@autoclosure
f({2 >1}())
f(2 > 1)
funciona. La llamadaf({2 > 1})
falla conerror: function produces expected type 'Bool'; did you mean to call it with '()'?
. Lo probé en un patio de recreo y con Swift REPL.func f(@autoclosure pred: () -> Bool)
Aquí hay un ejemplo práctico: mi
print
anulación (esto es Swift 3):Cuando dices
print(myExpensiveFunction())
, miprint
anulación eclipsa a Swiftprint
y se llama.myExpensiveFunction()
se envuelve así en un cierre y no se evalúa . Si estamos en modo Release, nunca se evaluará, porqueitem()
no se llamará. Por lo tanto, tenemos una versiónprint
que no evalúa sus argumentos en el modo Release.fuente
myExpensiveFunction()
? Si en lugar de usar el cierre automático, pasa la función para imprimirprint(myExpensiveFunction)
, ¿cuál sería el impacto? Gracias.Descripción de auto_closure de los documentos:
Y aquí está el ejemplo que Apple usa junto con él.
Básicamente, lo que significa es que pasa una expresión booleana como primer argumento en lugar de un cierre y automáticamente crea un cierre para usted. Es por eso que puede pasar falso al método porque es una expresión booleana, pero no puede pasar un cierre.
fuente
@auto_closure
aquí. El código funciona bien sin él:func simpleAssert(condition: Bool, message: String) { if !condition { println(message) } }
. Úselo@auto_closure
cuando necesite evaluar un argumento repetidamente (por ejemplo, si estaba implementando unawhile
función similar) o si necesita retrasar la evaluación de un argumento (por ejemplo, si estaba implementando un cortocircuito&&
).autoclosure
unawhile
función similar? No parece que me dé cuenta de eso. Muchas gracias de antemano.Esto muestra un caso útil de
@autoclosure
https://airspeedvelocity.net/2014/06/28/extending-the-swift-language-is-cool-but-be-careful/fuente
Es solo una forma de deshacerse de las llaves en una llamada de cierre, ejemplo simple:
fuente
@autoclosure
es un parámetro de función que acepta una función cocida (o tipo devuelto) mientras que un generalclosure
acepta una función sin procesarVeamos un ejemplo.
fuente