Dany:
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()
Czy istnieje sposób, aby completion
parametr (i action
) był typem, Action?
a także zachować @escaping
?
Zmiana typu powoduje następujący błąd:
Atrybut @escaping dotyczy tylko typów funkcji
Po usunięciu @escaping
atrybutu kod kompiluje się i uruchamia, ale nie wydaje się być poprawny, ponieważ completion
zamknięcie wymyka zakres funkcji.
@escaping
atrybutu powoduje kompilację i uruchomienie kodu” - Dzieje się tak, ponieważ, jak opisano w SR-2444 ,Action?
domyślnie stosuje się znaki ucieczki. Tak więc usunięcie@escaping
podczas korzystania z opcjonalnego zamknięcia spełnia Twoje potrzeby.Odpowiedzi:
Istnieje raport SR-2552, który
@escaping
nie rozpoznaje aliasu typu funkcji. dlatego błąd@escaping attribute only applies to function types
. możesz obejść ten problem, rozszerzając typ funkcji w sygnaturze funkcji:EDYCJA 1 ::
Właściwie byłem pod wersją beta xcode 8, w której błąd SR-2552 nie został jeszcze rozwiązany. naprawiając ten błąd, wprowadziłem nowy (ten, przed którym stoisz), który jest nadal otwarty. patrz SR-2444 .
Obejście, które @Michael Ilseman wskazał jako rozwiązanie tymczasowe, polega na usunięciu
@escaping
atrybutu z opcjonalnego typu funkcji, który utrzymuje funkcję jako ucieczkę .EDYCJA 2 ::
SR-2444 został zamknięty stwierdzając wyraźnie, że w parametrach pozycji zamknięcia nie ucieka i trzeba je było zaznaczone
@escaping
, aby je ucieczce, ale opcjonalne parametry są niejawnie ucieczki, ponieważ((Int)->())?
jest to synonimyOptional<(Int)->()>
, opcjonalne zamknięcia są ucieczki.źródło
@escaping may only be applied to parameters of function type func doStuff(stuff: String, completion: (@escaping ()->())?) {
a temporary solution is remove the @escaping attribute from optional function type, that keep the function as escaping.
Czy możesz to dalej wyjaśnić? Domyślna semantyczna w swift 3 nie jest ucieczką. Chociaż kompiluje się bez @escaping, obawiam się, że spowoduje problemy, ponieważ będzie traktowany jako nie-uciekający. Czy to nieprawda?@autoclosure
?from: lista mailingowa swift-users
Tak więc opcjonalnym parametrem funkcji jest domyślnie @escaping.
@noeascape domyślnie stosuje się tylko do parametru funkcji.
źródło
(()->Void)?
jest tym samym, co mówienie, że masz,Optional<()->Void>
aOptional
aby zachować własność, musiałby akceptować tylko@escaping
funkcje. Po trzecie, powinna to być akceptowana odpowiedź. Dziękuję Ci.Natknąłem się na podobny problem, ponieważ miksowanie
@escaping
i non-@escaping
jest bardzo mylące, szczególnie jeśli trzeba omijać zamknięcia.Skończyło się na przypisaniu domyślnej wartości no-op do parametru zamknięcia za pośrednictwem
= { _ in }
, co moim zdaniem ma większy sens:źródło
Mam to działające w Swift 3 bez żadnych ostrzeżeń tylko w ten sposób:
źródło
Ważne jest, aby zrozumieć na przykład to, że jeśli zmieni
Action
się doAction?
zamknięcia się ucieczką. Zróbmy więc to, co proponujesz:OK, teraz zadzwonimy
doStuff
:Cóż, ten wymóg pojawia się tylko w przypadku unikania zamknięć. Więc zamknięcie ucieka. Dlatego nie oznaczasz, że ucieka - już ucieka.
źródło