Swift 3 необязательный параметр экранирования закрытия
дано:
typealias Action = () -> ()
var action: Action = { }
func doStuff(stuff: String, completion: @escaping Action) {
print(stuff)
action = completion
completion()
}
func doStuffAgain() {
print("again")
action()
}
doStuff(stuff: "do stuff") {
print("swift 3!")
}
doStuffAgain()
есть ли способ сделать
4 ответа:
есть SR-2552 сообщаю об этом
@escaping
не распознает псевдоним типа функции. вот почему ошибка@escaping attribute only applies to function types
. вы можете обойти эту проблему, развернув тип функции в сигнатуре функции:typealias Action = () -> () var action: Action? = { } func doStuff(stuff: String, completion: (@escaping ()->())?) { print(stuff) action = completion completion?() } func doStuffAgain() { print("again") action?() } doStuff(stuff: "do stuff") { print("swift 3!") } doStuffAgain()
EDIT::
Я был на самом деле под бета-версией xcode 8, где ошибка SR-2552 еще не решено. исправив эту ошибку, ввел новый (тот, с которым вы столкнулись), который все еще открыт. видеть SR-2444.
решение Михаил Ilseman указано как временное решение удалить
@escaping
атрибут из необязательного типа функции,что сохранить функцию как побег.func doStuff(stuff: String, completion: Action?) {...}
от: swift-список рассылки пользователей
в принципе, @escaping допустим только на замыканиях в позиции параметра функции. Правило noescape-by-default применяется только к этим замыканиям в позиции параметра функции, в противном случае они экранируются. Агрегаты, такие как перечисления со связанными значениями (например, необязательные), кортежи, структуры и т. д., если они имеют замыкания, следуйте правилам по умолчанию для замыканий, которые не находятся в положении параметра функции, т. е. они убегающий.
поэтому необязательным параметром функции является @escaping по умолчанию.
@noeascape применяется только к параметру функции по умолчанию.
Я получил его работу в Swift 3 без каких-либо предупреждений только таким образом:
func doStuff(stuff: String, completion: (()->())? ) { print(stuff) action = completion completion?() }
я сталкиваюсь с подобной проблемой и потому, что смешивание @escaping и non @escaping очень запутанно, особенно если вам нужно передать закрытие. Я в конечном итоге с параметрами по умолчанию (который я думаю, имеет больше смысла)
func doStuff(stuff: String = "do stuff", completion: @escaping (_ some: String) -> Void = { _ in }) { completion(stuff) } doStuff(stuff: "bla") { stuff in print(stuff) } doStuff() { stuff in print(stuff) }