Notei ao escrever um assert
em Swift que o primeiro valor é digitado como
@autoclosure() -> Bool
com um método sobrecarregado para retornar um T
valor genérico , para testar a existência via LogicValue
protocol
.
No entanto, mantendo estritamente a questão em questão. Parece querer um @autoclosure
que retorne a Bool
.
Escrever um fechamento real que não aceita parâmetros e retorna um Bool não funciona, ele quer que eu chame o fechamento para compilá-lo, assim:
assert({() -> Bool in return false}(), "No user has been set", file: __FILE__, line: __LINE__)
No entanto, simplesmente passar um Bool funciona:
assert(false, "No user has been set", file: __FILE__, line: __LINE__)
Então, o que está acontecendo? O que é @autoclosure
?
Editar: @auto_closure
foi renomeado@autoclosure
f({2 >1}())
f(2 > 1)
funciona. A chamadaf({2 > 1})
falha comerror: function produces expected type 'Bool'; did you mean to call it with '()'?
. Eu testei em um playground e com o Swift REPL.func f(@autoclosure pred: () -> Bool)
Aqui está um exemplo prático - minha
print
substituição (aqui é Swift 3):Quando você diz
print(myExpensiveFunction())
, minhaprint
substituição obscurece a de Swiftprint
e é chamada.myExpensiveFunction()
é, portanto, envolto em um fechamento e não avaliado . Se estivermos no modo Release, ele nunca será avaliado, porqueitem()
não será chamado. Portanto, temos uma versãoprint
que não avalia seus argumentos no modo Release.fonte
myExpensiveFunction()
? Se, em vez de usar o fechamento automático, você passar a função para imprimir comoprint(myExpensiveFunction)
, qual seria o impacto? Obrigado.Descrição do auto_closure dos documentos:
E aqui está o exemplo que a Apple usa junto.
Basicamente, o que isso significa é que você passa uma expressão booleana como o primeiro argumento em vez de um fechamento e ele cria automaticamente um fechamento para você. É por isso que você pode passar falso para o método porque é uma expressão booleana, mas não pode passar um fechamento.
fonte
@auto_closure
aqui. O código funciona bem sem ele:func simpleAssert(condition: Bool, message: String) { if !condition { println(message) } }
. Use@auto_closure
quando precisar avaliar um argumento repetidamente (por exemplo, se você estiver implementando umawhile
função semelhante) ou se precisar atrasar a avaliação de um argumento (por exemplo, se você estiver implementando um curto-circuito&&
).autoclosure
umawhile
função semelhante a? Parece que não entendi isso. Muito obrigado antecipadamente.Isso mostra um caso útil de
@autoclosure
https://airspeedvelocity.net/2014/06/28/extending-the-swift-language-is-cool-but-be-careful/fonte
É apenas uma maneira de se livrar das chaves em uma chamada de encerramento, exemplo simples:
fonte
@autoclosure
é um parâmetro de função que aceita uma função cozida (ou tipo retornado) enquanto um generalclosure
aceita uma função brutaVamos dar uma olhada no exemplo
fonte